在 .net 中,我正在向 ssl 上的 Web 服务发出 Web 请求。对于密码学,我必须使用受 PIN 码保护的 USB 安全卡设备的证书
我进行网络请求的代码...
Dim lRequest As HttpWebRequest
lRequest = WebRequest.Create(lAddress)
lRequest.Method = "POST"
lRequest.KeepAlive = True
lRequest.ProtocolVersion = HttpVersion.Version11
lRequest.ContentType = "text/xml; charset=utf-8"
lRequest.ContentLength = lRequestContent.Length
lRequest.Headers.Add("SOAPAction", "")
lRequest.ClientCertificates.Add(gcert)
并且在此之前为了使通话正常...
ServicePointManager.ServerCertificateValidationCallback = New RemoteCertificateValidationCallback(AddressOf ValidateServerCertificate)
Public Function ValidateServerCertificate(ByVal sender As Object, ByVal certificate As X509Certificate, ByVal chain As X509Chain, ByVal sslPolicyErrors As SslPolicyErrors) As Boolean
Return True
End Function
其中 gcert 是来自 Windows 个人商店的证书...
Public gcert As X509Certificate2
Dim store As New X509Store(StoreName.My, StoreLocation.CurrentUser)
store.Open(OpenFlags.ReadOnly Or OpenFlags.OpenExistingOnly)
...
所有这一切都很好:当我发送我的 webRequest 时,系统会提示我输入 PIN,然后我会收到来自 Web 服务的响应。如果我正在拨打其他电话,我不会再次提示我输入 PIN,但所有电话都可以正常工作。
但现在我的问题是:我想清除 PIN 缓存,以便在每次调用时再次提示输入 PIN,或者如果我告诉我的程序这样做(例如“断开”按钮或 10 百万后超时)我无法成功重置 PIN,以便在下次通话时再次收到提示...
经过一些研究,我尝试了这个:
<DllImport("schannel.dll", SetLastError:=True)> _
Private Function SslEmptyCache(ByVal pszTargetName As IntPtr, ByVal dwFlags As UInt32) As Boolean
End Function
Public Function SslEmptyCache() As Boolean
WriteTrace("> SslEmptyCache")
Try
Return SslEmptyCache(IntPtr.Zero, 0)
Catch ex As Exception
WriteTrace("Echec SslEmptyCache")
End Try
Return False
End Function
和这个
ClearPINCache(gcert.PrivateKey)
Public Function ClearPINCache(ByVal key As RSACryptoServiceProvider) As Boolean
Const PP_KEYEXCHANGE_PIN As UInt32 = 32
Const PP_SIGNATURE_PIN As UInt32 = 33
Dim bretval As Boolean = False
Dim hProv As IntPtr = IntPtr.Zero
If (CryptAcquireContext(hProv, key.CspKeyContainerInfo.KeyContainerName, key.CspKeyContainerInfo.ProviderName, CUInt(key.CspKeyContainerInfo.ProviderType), 0)) Then
If ((CryptSetProvParam(hProv, PP_KEYEXCHANGE_PIN, Nothing, 0) = True) And (CryptSetProvParam(hProv, PP_SIGNATURE_PIN, Nothing, 0) = True)) Then
bretval = True
End If
End If
If (hProv <> IntPtr.Zero) Then
CryptReleaseContext(hProv, 0)
hProv = IntPtr.Zero
End If
Return bretval
End Function
clearPINCahe 函数似乎什么也没做
SslEmptyCache 函数清除了一些东西,但在下一次调用后,我没有再次提示输入 PIN,但我收到此错误“请求已中止:无法创建 SSL/TLS 安全通道。” 就像我没有在通话中提供 clientCertificate
有人知道我缺少什么吗?
谢谢