Как сделать запрос POST с помощью HttpClient с сертификатом PFX

Я использую последнюю версию .NET 8 HttpClient для вызова конечной точки API.

Это мой код:

var cert = new X509Certificate("myCert.pfx", "mypass");

var handler = new HttpClientHandler
{
    ClientCertificateOptions = ClientCertificateOption.Manual
};

handler.ClientCertificates.Add(cert);

using var httpClient = new HttpClient(handler);

var response = await httpClient.PostAsJsonAsync("https://<my-url>");

var resultString = await response.Content.ReadAsStringAsync();

Он сгенерировал следующее исключение:

System.Net.Http.HttpRequestException: An error occurred while sending the request.
 ---> System.IO.IOException: The decryption operation failed, see inner exception.
 ---> System.ComponentModel.Win32Exception (0x80090326): The message received was unexpected or badly formatted.
   --- End of inner exception stack trace ---
   at System.Net.Security.SslStream.ReadAsyncInternal[TIOAdapter](Memory`1 buffer, CancellationToken cancellationToken)
   at System.Runtime.CompilerServices.PoolingAsyncValueTaskMethodBuilder`1.StateMachineBox`1.System.Threading.Tasks.Sources.IValueTaskSource<TResult>.GetResult(Int16 token)
   at System.Net.Http.HttpConnection.InitialFillAsync(Boolean async)
   at System.Net.Http.HttpConnection.SendAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)

Кажется, это говорит о том, что закрытый ключ не работает должным образом. Я использовал тот же файл сертификата и пароль в Postman, и запрос был выполнен успешно и дал значимые результаты.

Вот некоторые из вещей, которые я пробовал:

  1. Дважды проверил мой пароль
  2. Разбивка файла PFX на сертификат и закрытый ключ
  3. Укажите запрос как TLS 1.2.

Ничего из вышеперечисленного не помогло.

Вы устанавливаете корневой сертификат?

Qiang Fu 16.08.2024 03:32
HttpClientHandler предназначен только для .NET Framework и .NET Core 1 + 2, а не для .NET 8 — вам следует использовать SocketsHttpHandler (да, это сбивает с толку и непоследовательно документировано).
Dai 16.08.2024 08:28
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
3
54
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Ваш код смешивает типы, предназначенные для .NET Framework (4.x) и более старых версий .NET Core; якобы код, использующий их, должен работать без изменений в .NET 8, но программа не будет работать так хорошо, как могла бы - хотя на практике я обнаружил, что это приведет к ошибкам типа «Полученное сообщение было неожиданным или плохо отформатировано».

Я предлагаю вам изменить свой код на это и покрутить его:

X509Certificate2 clientCert = new X509Certificate2(
    fileName: "myCert.pfx",
    password: "mypass"
);

if ( !clientCert.HasPrivateKey ) throw new InvalidOperationException( "Private key not loaded." );

SocketsHttpHandler socksHandler = new SocketsHttpHandler
{
    SslOptions =
    {
//      CipherSuitesPolicy = new CipherSuitesPolicy( ... ) // Only uncomment this if the underlying TLS error is due to a client/server disagreement over what TLS algos to use and this is the *only* way to resolve it.
        ClientCertificates = new X509CertificateCollection()
        {
            clientCert
        },
//      SslProtocols = SslProtocols.Tls12 // Only uncomment this if you actually really need to specify exactly TLS 1.2. By default it will be negotiated.
    }
};

using HttpClient httpClient = new HttpClient( socksHandler );

using HttpResponseMessage response = await httpClient.PostAsJsonAsync( "https://<my-url>", etc );

String responseBody = await response.Content.ReadAsStringAsync();

Другие вопросы по теме

ASP.NET Core MVC: модель привязывает все значения ключей POSTed к свойству, не соответствующему имени, в дополнение к привязке модели по умолчанию?
Как отфильтровать столбец в таблице данных jQuery
Как я могу использовать IFormFile в .Net 8.0 без устаревших пакетов
Как фильтровать массив объектов, равный имени и содержащий значение?
Таблица данных JQuery – сортировка столбцов не работает в
Ограничения на загрузку файлов .Net 8. Попытка загрузить файл размером 89 МБ на мой контроллер API
Контекст Testcontainers .NET 8 db, похоже, не обновляется в [Факт], проблема решена, ищет объяснение
Переписать удаление служебной шины Azure
Невозможно вставить явное значение для столбца идентификаторов в таблице «Обсуждаемые продукты», если для параметра IDENTITY_INSERT установлено значение OFF
Является ли этот код Blazor/EF Core эффективным и безопасным использованием DbContext и доступом к теневым свойствам?