Мы пытаемся подключиться к конечной точке, которая не делает ничего, кроме проверки правильности подключения сертификата.
Наш код прост:
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
using (var handler = new HttpClientHandler())
{
var rawcert = File.ReadAllText(@"C:\OpenSSL\bin\cert.pem");
var rawkey = File.ReadAllText(@"C:\OpenSSL\bin\private.key");
var provider = new CertificateFromFileProvider(rawcert, rawkey);
var certificate = provider.Certificate;
handler.ClientCertificateOptions = ClientCertificateOption.Manual;
handler.ClientCertificates.Add(certificate);
handler.ServerCertificateCustomValidationCallback +=
(HttpRequestMessage req, X509Certificate2 cert2, X509Chain chain, SslPolicyErrors err) =>
{
Trace.WriteLine($"Sender: {req}");
Trace.WriteLine($"cert: {cert2}");
Trace.WriteLine($"chain: {chain}");
Trace.WriteLine($"sslPolicyErrors: {err}");
return true;
};
using (var client = new HttpClient(handler))
{
var response = await client.GetStringAsync("https://{uri}/mtlsTest");
return response;
}
}
(Это среда для песочницы для подтверждения концепции, поэтому пока что нам удобно сокращать ValidationCallback.)
Мы видим, что прикрепленный сертификат выглядит правильно сформированным в обратном вызове (происхождение и тема соответствуют ожидаемым), но мы получаем ответ от сервера, который указывает, что сертификат не был прикреплен.Почему это может быть?
Мы также пытались экспортировать сертификат как pfx
и прикрепить его вместо исходного pem
файла с идентичным результатом.
Обновление
Благодаря полезным комментариям ниже от @bartonjs и @ Crypt32 мы попытались добавить закрытый ключ (используя удобный пакет Nuget от @ stef-heyenrath), но хотяэто приводит к тому, что сертификат, который мы добавляем к обработчику, показывает HasPrivateKey=true
:
... при срабатывании ValidationCallback трассировки X509Certificate2
HasPrivateKey=false
:
... и мы получаем ту же ошибку, что и раньше - сервер никогда не подтверждает получение сертификата.
Если мы упаковываем .pem
и закрытый ключ в .pfx
, используя open ssl: pkcs12 -inkey private.key -in cert.pem -export -out cert.pfx
..., тогда мы снова получаем тот же результат, и сервер не может найти сертификат.Аналогично, если мы установим сертификат в личном магазине и загрузим его оттуда (тот же результат).Инспекция в Wireshark показывает, что сертификат просто никогда не прикрепляется.
Почему это так?Полный пересмотренный код выше.