Дополнительная информация в конце после комментариев от 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