WebRequest с взаимной аутентификацией - PullRequest
0 голосов
/ 10 апреля 2019

Дополнительная информация в конце после комментариев от Crypt32 (спасибо Crypt32!)

Я должен отправить данные на сервер. Мне нужна взаимная аутентификация: сервер должен быть уверен, что это я, и я должен быть уверен, что сервер действительно является сервером, которому я доверяю. Это должно быть в программе Windows.

Чтобы идентифицировать себя, сервер отправит мне сертификат, выданный центрами сертификации, которому я доверяю: корневой сертификат и промежуточный сертификат:

  • Root CA-G2.PEM
  • Средний CA-G2.PEM

Чтобы идентифицировать меня, организация дала мне сертификат и закрытый ключ

  • Root CA-G3.PEM
  • Промежуточное звено CA-G3.PEM
  • MyCertificate.CRT (= pem) и MyCertificate.Private.Key (= RSA)

Я импортировал все корневые сертификаты и промежуточные сертификаты в хранилище ключей Windows.

Чтобы отправить сообщение:

const string url = "https://...//Deliver";
HttpWebRequest webRequest = WebRequest.CreateHttp(url);

// Security:
webRequest.AuthenticationLevel=AuthenticationLevel.MutualAuthRequired;
webRequest.Credentials = CredentialCache.DefaultCredentials;

// Should I add my certificate?
X509Certificate myCertificate = new X509Certificate("MyCertificate.CRT");

// Should I add Certificate authorities?
// only the CA-G2 authorities, so my WebRequest can trust the certificate
// that will be sent by the Server?
// or Should I also add the CA-G3 who issued MyCertificate

// and what about MyCertificate.Private.Key, the RSA file?

// Fill the rest of the WebRequest:
webRequest.Method = "Post";
webRequest.Accept = "text/xml";
webRequest.Headers.Add("SOAP:Action");
webRequest.ContentType = "text/xml;charset=\"utf-8\"";
... etc

// do the call and display the result
using (WebResponse response = webRequest.GetResponse())
{
    using (var reader = new StreamReader(response.GetResponseStream()))
    {
        string soapResult = reader.ReadToEnd();
        Console.WriteLine(soapResult);
    }
}

WebResponse не указывает на какую-либо ошибку. Возвращаемые данные являются пустой (ненулевой) строкой. Тем не менее:

response.StatusCode == NoContent (204)
soapResult == String.Empty
response.IsMutuallyAuthenticated == false

Ожидается NoContent и результат с пустыми данными. Ложное IsMutuallyAuthenticated указывает, что что-то не так с моей аутентификацией?

Добавлена ​​информация

Crypt32 предложил мне преобразовать MyCertificate.CRT и MyCertificate.Private.Key в один файл PFX (или P12).

Для этого я использую openssl.

Я объединил файлы CA-G3 в один TrustG3.Pem и создал файл P12:

openssl.exe pkcs12 -export -name "<some friendly name>"
                   -certfile TrustG3.Pem
                   -in MyCertificate.CRT
                   -inkey MyCertificate.Private.Key
                   -out MyCertificate.P12

После предоставления пароля был создан правильный файл Pkcs12 (PFX). Исходный код немного меняется:

HttpWebRequest webRequest = WebRequest.CreateHttp(url);

// Security:
webRequest.AuthenticationLevel=AuthenticationLevel.MutualAuthRequired;
webRequest.Credentials = CredentialCache.DefaultCredentials;
var p12Certificate = new X509Certificate("MyCertificate.P12", "my password");
webRequest.ClientCertificates.Add(p12Certificate);

Увы, это не помогло. WebResponse по-прежнему говорит:

response.IsMutuallyAuthenticated == false

1 Ответ

0 голосов
/ 10 апреля 2019

Указывает ли false IsMutuallyAuthenticated, что что-то не так с моей аутентификацией?

Да, это так.Потому что вы добавляете только открытую часть сертификата клиента.Не указан связанный закрытый ключ.Либо используйте сертификат из хранилища сертификатов (при условии, что хранилище сертификатов содержит закрытый ключ), либо импортируйте сертификат из PFX.

Обновление:

теперь ваш код аутентификации клиента выглядит правильно.Следующий шаг - проверить, доверяет ли ваш клиентский сертификат серверу.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...