HttpWebRequest, похоже, не отправляет сертификат SSL клиента
Я пытаюсь использовать HttpWebRequest
запрос удаленный сервер с nginx. Мне нужно предоставить сертификат клиента для завершения соединения.
Я делаю следующее:
Dim Request As HttpWebRequest = DirectCast(WebRequest.Create(Url), HttpWebRequest)
Dim Cert = SSL.GetClientCertificate()
Request.ClientCertificates.Clear()
Request.ClientCertificates.Add(Cert)
Dim Response As WebResponse = Request.GetResponse()
(SSL.GetClientCertificate
это просто вспомогательный метод, который открывает My
хранить на локальном компьютере и извлекает соответствующий сертификат (как X509Certificate2
). Возвращается правильный сертификат. Я также попытался просто загрузить сертификат из файла с идентичным результаты.)
как обстоят дела, когда я добираюсь до Dim Response As...
и он фактически пытается открыть соединение, я получаю 400 плохой запрос, возвращенный со следующим телом:
400 Bad Request
No required SSL certificate was sent
-----------------------------------
nginx/1.0.10
мы используем наш собственный CA, который имеет сертификат в LocalMachineTrustedRootCertificationAuthorities
на моей машине. Сертификат клиента действителен, но не проходит проверку, поскольку наш ЦС не предоставляет OCSP конечной точки. Если я создам X509Chain и попрошу его проверить цепочку без проверки отзыва, все проходит.
Итак, мой вопрос... Почему сертификат не отправляется вместе с запросом? Я не считаю, что он должен пытаться проверить сертификат клиента перед его отправкой (это задание серверов).
Я не буду наводнять вас в журналах Wireshark, но клиент не отправляет сертификат. Короче, я понял ...
- [Out] Клиент Привет
- [In] Сервер Привет
- [In] Сертификат
- [In] Сервер Hello Done
- [Вне] Сертификат, Обмен Ключа Клиента, Спецификации Шифра Изменения, Зашифрованное Сообщение Рукопожатия
- [In] Изменить Спецификацию Шифра, Зашифрованное Сообщение Рукопожатия
- [Out] данные приложения (предположительно запрос GET)
- [In] данные приложения (предположительно 400)
- [In] зашифрованное предупреждение (завершает канал)
Я думаю nginx делает что-то умное, где вместо того, чтобы умереть когда я не могу отправить сертификат, он пересматривает, чтобы позволить ему отправить тело ответа 400 (вместо того, чтобы не создавать канал в первую очередь)
в любом случае, я не отправляю сертификат, который является реальной проблемой. Кто-нибудь знает почему?
в случае, если это помогает, журналы nginx настаивают, что сертификат не отправляется (в отличие от сертификата, являющегося недействительным):
2012/11/22 14:16:26 [info] 27755#0: * 799 клиент не отправил требуемый сертификат SSL при чтении заголовков клиентских запросов клиент: 10.0.0.200, сервер: 10.0.0.100, запрос: "GET / state HTTP / 1.1", хост:"10.0.0.100"
пожалуйста, не используйте код ниже-он неэффективен, ненадежен и использовался только для тестирования
Re: получение сертификата:
Public Shared Function GetClientCertificate() As X509Certificate2
Dim Store As New X509Store(StoreName.My, StoreLocation.LocalMachine)
Dim Ret As X509Certificate2 = Nothing
Try
Store.Open(OpenFlags.ReadOnly Or OpenFlags.OpenExistingOnly)
For Each Certificate In Store.Certificates
If Certificate.SubjectName.Name = "The subjectname of our certificate" Then
Ret = Certificate
Exit For
End If
Next
Finally
Store.Close()
End Try
Return Ret
End Function
1 ответов
вам нужен сертификат с доступным закрытым ключом, чтобы иметь возможность использовать его в качестве сертификата клиента (или сервера, если на то пошло).
нормально хранить сертификат в хранилище сертификатов машины, если вы предоставляете любому пользователю, которому требуется использовать сертификат, доступ к его закрытым ключам. Вы не можете аутентифицировать клиента с помощью a .cer, потому что он содержит только открытый ключ. Вы можете проверить все, установив сертификат клиента для своего пользователя, и доступ к URL с помощью браузера. Если вы получаете всплывающее окно для выбора сертификата, он установлен правильно (для этого пользователя).