У меня есть простой фрагмент кода соединения https, который хорошо работает с одним хостом SSL, подключаясь, даже если корневой центр сертификации не является доверенным (это изолированная среда, поэтому нас не беспокоит дыра в безопасности, которую это создает, поскольку сейчас) и загрузив сертификат и ключ из текстовых файлов с помощью пакета Nuget OpenSSL.X509Certificate2Provider:
public async Task Register() { ServicePointManager.Expect100Continue = true; ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; ServicePointManager.ServerCertificateValidationCallback = (отправитель, сертификат, цепочка, sslPolicyErrors) => true; используя (обработчик var = новый HttpClientHandler()) { var rawcert = File.ReadAllText(@"C:\OpenSSL\bin\certTransport.pem"); var rawkey = File.ReadAllText(@"C:\OpenSSL\bin\privateKeyTransport.key"); поставщик вар = новый сертификат FromFileProvider (rawcert, rawkey); вар сертификат = поставщик.Сертификат; handler.ClientCertificateOptions = ClientCertificateOption.Manual; handler.ServerCertificateCustomValidationCallback += (HttpRequestMessage req, X509Certificate2 cert2, цепочка X509Chain, ошибка SslPolicyErrors) => { вернуть истину; }; обработчик.ClientCertificates.Add(сертификат); используя (var client = новый HttpClient (обработчик)) { client.BaseAddress = новый Uri("https://{uri}/"); var ответ = ждут client.GetStringAsync("регистрация"); обратный ответ; } } } Когда я указываю этот код на другой хост, который должен быть защищен точно таким же образом, я получаю следующую ошибку: System.Net.WebException: запрос был прерван: не удалось создать безопасный канал SSL/TLS.
Покопавшись в журналах, я обнаружил: Информация System.Net: 0: [35036] AcquireCredentialsHandle (пакет = поставщик протокола единой безопасности Microsoft, намерение = исходящий, scc = System.Net.SecureCredential) Ошибка System.Net: 0: [35036] Ошибка AcquireCredentialsHandle() с ошибкой 0X8009030D.
При поиске этого стека я обнаружил множество ошибок, связанных с разрешениями хранилища сертификатов, но сертификат клиента в данном случае не загружается из хранилища.
Я также обнаружил множество проблем, связанных с SecurityProtocolType. Я проверил, что сервер использует только Tls1.2.
Я вызываю код из модульного теста в VS 2017 Enterprise, работающего с правами администратора на Win10 x64. Код содержится в библиотеке классов .Net 4.7, а не в IIS.
Что может быть причиной этой проблемы?
ОБНОВЛЕНИЕ Следуя полезным комментариям @Jeroen Mostert ниже, я попробовал выполнить базовый тест соединения с OpenSSL. Слегка анонимизированные результаты:
OpenSSL> s_client -connect {REMOVED}:443 -CAfile C:\OpenSSL\bin\archive-ii\transport-production-new\certTransport.pem ПОДКЛЮЧЕН(000001F0) глубина = 2 C = ГБ, O = ОК, CN = {УДАЛЕН} Корневой центр сертификации ошибка проверки: номер = 19: самоподписанный сертификат в цепочке сертификатов --- Цепочка сертификатов 0 с:/C=GB/O={REMOVED}/OU={REMOVED}/CN={REMOVED} i:/C=GB/O={REMOVED}/CN={REMOVED} Выдающий центр сертификации 1 с:/C=GB/O={REMOVED}/CN={REMOVED} Выдающий центр сертификации i:/C=GB/O={REMOVED}/CN={REMOVED} Корневой центр сертификации 2 с:/C=GB/O={REMOVED}/CN={REMOVED} Корневой центр сертификации i:/C=GB/O={REMOVED}/CN={REMOVED} Корневой центр сертификации --- Сертификат сервера -----НАЧАТЬ СЕРТИФИКАТ----- {УДАЛЕННЫЙ} -----КОНЕЦ СЕРТИФИКАТА----- subject=/C=GB/O={REMOVED}/OU={REMOVED}/CN={REMOVED} Issuer=/C=GB/O={REMOVED}/CN={REMOVED} Выпускающий центр сертификации --- Допустимые имена центров сертификации клиентских сертификатов /C=GB/O={REMOVED}/CN={REMOVED} Выдающий центр сертификации /C=GB/O={REMOVED}/CN={REMOVED} Корневой центр сертификации Типы сертификатов клиента: знак RSA, знак DSA, знак ECDSA. Запрошенные алгоритмы подписи: RSA+SHA512:DSA+SHA512:ECDSA+SHA512:RSA+SHA384:DSA+SHA384:ECDSA+SHA384:RSA+SHA256:DSA+SHA256:ECDSA+SHA256:RSA+SHA224:DSA+SHA224:ECDSA+ SHA224:RSA+SHA1:DSA+SHA1:ECDSA+SHA1 Алгоритмы общей запрошенной подписи: RSA+SHA512:DSA+SHA512:ECDSA+SHA512:RSA+SHA384:DSA+SHA384:ECDSA+SHA384:RSA+SHA256:DSA+SHA256:ECDSA+SHA256:RSA+SHA224:DSA+SHA224:ECDSA +SHA224:RSA+SHA1:DSA+SHA1:ECDSA+SHA1 Дайджест однорангового подписания: SHA512 Временной ключ сервера: ECDH, P-256, 256 бит. --- При подтверждении SSL было прочитано 5155 байт и записано 446 байт. --- Новый, TLSv1/SSLv3, шифр ECDHE-RSA-AES128-GCM-SHA256. Открытый ключ сервера имеет длину 2048 бит. Поддерживается безопасное повторное согласование Сжатие: НЕТ Расширение: НЕТ ALPN не согласован SSL-сессия: Протокол: TLSv1.2. Шифр: ECDHE-RSA-AES128-GCM-SHA256. Идентификатор сессии: Идентификатор сеанса-ctx: Мастер-ключ: {УДАЛЕН} Ключ-Аргумент: Нет Идентичность PSK: Нет Подсказка для идентификации PSK: Нет Имя пользователя SRP: Нет Время начала: 1527164830 Тайм-аут: 300 (сек) Проверьте код возврата: 19 (самозаверяющий сертификат в цепочке сертификатов) --- Там что-то не так?
Я также просмотрел журнал CAPI2 (как предложено в комментариях). Это показывает ошибки, связанные с недоверием корневого сертификата, например:

Означает ли это, что мои обратные вызовы проверки не работают? Если да, то есть ли идеи, почему это происходит?
Дополнительные обновления:
Если я удалю строку кода, которая прикрепляет сертификат, то ошибка исчезнет — я доберусь до конечной точки теста MTLS (но, конечно, провалю тест MTLS, который там проводится).
Что это означает? Проблема с самим сертификатом?