Можно ли использовать файл .p12 с сертификатами CA в C# без их импорта в хранилище сертификатов - PullRequest
3 голосов
/ 08 мая 2020

У меня есть файл сертификата .p12 с тремя сертификатами. 2 из них - сертификаты CA.

Если я использую curl (7.70 на Win10), я могу сделать: curl -s -S -i --cert Swish_Merchant_TestCertificate_1234679304.p12: swi sh --cert-type p12 --tlsv1.2 --header "Content-Type: application / json" https://mss.cpc.getswish.net/swish-cpcapi/api/v1/paymentrequests --data-binary @ jsondata. json

Curl будет использовать CA сертификаты в файле p12 при подключении к серверу.

С другой стороны, если я попытаюсь сделать что-то подобное в. net core (3.1), произойдет сбой с сообщением об ошибке «Полученное сообщение было неожиданным или плохо отформатирован. "

var handler = new HttpClientHandler();
var certs = new X509Certificate2Collection();
certs.Import(@"Swish_Merchant_TestCertificate_1234679304.p12", "swish", X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet);
foreach (var cert in certs)
{
    handler.ClientCertificates.Add(cert);
}
var client = new HttpClient(handler);
var url = "https://mss.cpc.getswish.net/swish-cpcapi/api/v1/paymentrequests";
var request = new HttpRequestMessage()
{
    RequestUri = new Uri(url),
    Method = HttpMethod.Post,
};
request.Content = new StringContent(System.IO.File.ReadAllText(@"jsondata.json"), Encoding.UTF8, "application/json");
request.Headers.Add("accept", "*/*");
var response = await client.SendAsync(request);

Используя Wireshark, я увидел, что curl отправляет все три сертификата из файла p12, тогда как. net core отправляет только один. См. Изображения ниже.

Если я устанавливаю сертификаты CA в «Персональный сертификат» для «Текущего пользователя», то ядро ​​net также отправляет все три сертификата, и он работает.

Вопрос : Нужно ли мне устанавливать сертификаты CA (в хранилище сертификатов) при использовании ядра. net или есть способ заставить его вести себя так же, как curl, который использует сертификаты из файла p12?

Wireshark curl: Whireshark when making call with curl

Wireshark. net core: Wireshark when making call with .net core

1 Ответ

3 голосов
/ 08 мая 2020

Краткий ответ: нет *.

Wordier intro: SslStream выбирает один сертификат из коллекции ClientCertificates, используя данные, которые (были исторически, но больше не обычно) отправляются сервером TLS о соответствующих корнях (и если ни один из них не применим, он выбирает первое, где HasPrivateKey истинно). В процессе выбора каждый сертификат кандидата проверяется изолированно, и система запрашивает разрешение цепочки. На Windows выбранный сертификат затем отправляется в системные библиотеки для «мы делаем TLS сейчас», что (IIR C) является источником ограничений. (macOS и Linux сборки из. NET Core просто пытаются поддерживать поведенческую паритетность)

После выбора сертификата выполняется последняя цепочка, чтобы определить, какие сертификаты включить в рукопожатие. без контекста чего-либо еще из коллекции ClientCertificates.

Если вы знаете, что ваша коллекция представляет собой одну цепочку, лучший ответ - импортировать элементы CA в хранилище CertificateAuthority пользователя. Это хранилище не доверяет сертификатам CA, на самом деле это просто кеш, который используется при построении цепочек.

Кроме того, вам не нужен PersistKeySet и, вероятно, не нужен MachineKeySet: What является обоснованием для всех различных X509KeyStorageFlags?

var handler = new HttpClientHandler();

using (X509Store store = new X509Store(StoreName.CertificateAuthority, StoreLocation.CurrentUser))
{
    store.Open(OpenFlags.ReadWrite);

    var certs = new X509Certificate2Collection();
    certs.Import(@"Swish_Merchant_TestCertificate_1234679304.p12", "swish", X509KeyStorageFlags.DefaultKeySet);

    foreach (X509Certificate2 cert in certs)
    {
        if (cert.HasPrivateKey)
        {
            handler.ClientCertificates.Add(cert);
        }
        else
        {
            store.Add(cert);
        }
    }
}

var client = new HttpClient(handler);
...

* Если в вашей системе уже импортирована цепочка CA, она будет работать. В качестве альтернативы, если цепочка CA использует расширение доступа к информации о полномочиях для публикации sh загружаемой копии сертификата CA, механизм цепочки найдет ее, и все будет работать.

...