Я пытаюсь создать интеграцию со шведским провайдером платежей GetSwish. Гениально они решили использовать клиентские сертификаты в качестве аутентификации вместо хеширования и делиться секретами, как практически любой другой поставщик платежей на планете. По какой-то причине они решили использовать самозаверяющие клиентские сертификаты вместо того, чтобы заключить оптовую сделку с Comodo, Verisign или любым другим центром сертификации.
При использовании HttpClient для подключения к службе с сертификатом, который они предоставляют, базовый HttpClientHandler пытается проверить действительность сертификата, связавшись с ЦС. Это, очевидно, не удается, так как сертификат самоподписан. Это можно обойти, установив сертификат в хранилище сертификатов на серверах, которое замыкает цепь проверки. Приложение, которое я создаю, будет размещено в среде PAAS, где хранилище сертификатов недоступно.
Моя текущая идея состоит в том, чтобы разделить большие части пространства имен System.Net.Http из https://github.com/dotnet/corefx и фактически снизить безопасность соединения, удалив проверку, чтобы можно было выполнять запросы. Содержащие финансовые операции. Это не совсем правильно со мной.
Комментарий от поддержки разработчиков GetSwish гласил: «Windows всегда делает что-то странное и нестандартное», за которым не последовало никакой помощи и удачи.
Следующий код работает, когда файл .p12 установлен в хранилище сертификатов компьютеров:
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls11;
X509Certificate2 swishCertificate = new X509Certificate2(System.IO.File.ReadAllBytes("cert1231181189.p12"), "swish", X509KeyStorageFlags.Exportable | X509KeyStorageFlags.PersistKeySet); HttpClientHandler handler = new PartialHttpClientHandler();
handler.ClientCertificates.Add(swishCertificate);
// Validate the server certificate. Because ofcourse it doesn't work properly either.
handler.ServerCertificateCustomValidationCallback += ServerCertificateCustomValidationCallback;
handler.CheckCertificateRevocationList = false;
HttpClient client = new HttpClient(handler);