в .net я делаю веб-запросы к веб-службе по ssl. Для криптографии я должен использовать сертификат с USB-устройства защищенной карты, защищенный PIN-кодом.
Мой код для выполнения веб-запроса...
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)
...
Все это работает нормально: когда я отправляю свой веб-запрос, мне предлагается ввести PIN-код, а затем я получаю ответ от веб-службы. И если я делаю другие звонки, мне снова не запрашивают 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 в вызове
Кто-нибудь знает, что мне не хватает?
Спасибо