Проблемы с сертификатом клиента в Windows 2022 / IIS10 для взаимных TLS в .NET 4.8C#

Место общения программистов C#
Ответить
Anonymous
 Проблемы с сертификатом клиента в Windows 2022 / IIS10 для взаимных TLS в .NET 4.8

Сообщение Anonymous »

Мы общаемся с внешним сервером через httpclient, используя взаимные TLS. Они предоставили нам следующую команду OpenSSL для создания закрытого ключа и CSR: < /p>

Код: Выделить всё

openssl genrsa -aes256 -out private_key.pem 2048

Код: Выделить всё

openssl req -new -sha256 -key private_key.pem -out ibanity.csr -subj "/C=BE/O=xxx/OU=xxx/CN=xxx/serialNumber=5ffd8759-e3c4-4952-9db8-8ed2d5b52b55"

С помощью этого CSR они предоставляют нам сертификат ("sertiate.pem").
При использовании curl мы можем хорошо общаться с их сервером, используя взаимный TL, используя сертификат. .Net, мы используем: < /p>

Код: Выделить всё

openssl pkcs12 -export -out certificate.pfx -inkey private_key.pem -in certificate.pem

, однако, мы не можем загрузить сертификат в MMC, поскольку он дает ошибку, что пароль неверный. После исследования это проблема в Windows Server 2016 и ранее, поскольку они не поддерживают AES256. Но мы используем Windows 2022, и он все еще не работает.

Код: Выделить всё

var pemCert = File.ReadAllText(_certFile);
var pemKey = File.ReadAllText(_certKeyFile);

using (var textReader = new StringReader(pemKey))
using (var pemReader = new PemReader(textReader, new PasswordFinder(_certPass)))
{
// Read key information directly
var rsaPrivatekey = (RsaPrivateCrtKeyParameters)pemReader.ReadObject();
var rsaPublicKey = new RsaKeyParameters(false, rsaPrivatekey.Modulus, rsaPrivatekey.PublicExponent);
var keyPair = new AsymmetricCipherKeyPair(rsaPublicKey, rsaPrivatekey);

// Parse the certificate
var cert = (Org.BouncyCastle.X509.X509Certificate)new PemReader(new StringReader(pemCert)).ReadObject();

// Create PKCS#12 store with DER encoding for better performance
var store = new Pkcs12StoreBuilder().SetUseDerEncoding(true).Build();

// Set certificate and key entry
var certEntry = new X509CertificateEntry(cert);
store.SetCertificateEntry("", certEntry);
store.SetKeyEntry("", new AsymmetricKeyEntry(keyPair.Private), new[] { certEntry });

// Write to memory and create X509Certificate2
using (var ms = new MemoryStream(4096))
{
store.Save(ms, System.Array.Empty(), new SecureRandom());
x509Cert = new X509Certificate2(ms.ToArray());
}
}
Мы загружаем x509cert в httphandler , создать httpclient и запустить связь. Когда мы впервые запускаем рутину (и создаем httpclient в первый раз), она не удается с сообщением:

Код: Выделить всё

An error occurred while sending the request. System.Net.WebException:
The request was aborted: Could not create SSL/TLS secure channel
< /code>
При запуска той же процедуры во второй раз он работает. Если мы запустим его локально на компьютере DEV (Windows 11, Visual Studio), он всегда работает. При толчке кода к производству мы обнаружили, что были проблемы.System.Net Information: 0 : [1760] SecureChannel#43948301 - Certificate is of type X509Certificate2 and contains the private key.
System.Net Information: 0 : [1760] SecureChannel#43948301::.AcquireClientCredentials, new SecureCredential() (flags=(ValidateManual, NoDefaultCred, SendAuxRecord, UseStrongCrypto), m_ProtocolFlags=(Tls13Client), m_EncryptionPolicy=RequireEncryption)
System.Net Information: 0 : [1760] AcquireCredentialsHandle(package = Microsoft Unified Security Protocol Provider, intent  = Outbound, scc     = System.Net.SecureCredential2)
System.Net Error: 0 : [1760] AcquireCredentialsHandle() failed with error 0X8009030D.
System.Net Information: 0 : [1760] AcquireCredentialsHandle(package = Microsoft Unified Security Protocol Provider, intent  = Outbound, scc     = System.Net.SecureCredential2)
System.Net Error: 0 : [1760] AcquireCredentialsHandle() failed with error 0X8009030D.
System.Net Error: 0 : [1760] Exception in HttpWebRequest#55258087:: - The request was aborted: Could not create SSL/TLS secure channel..
< /code>
Каждый раз, когда мы запускаем процедуру, она работает правильно - до тех пор, пока пул приложений переработает или веб -сайт не будет остановлен и перезапущен.  После этого ошибка возникает один раз, и тогда все снова работает нормально.System.Net Information: 0 : [8960] SecureChannel#2781196 - Certificate is of type X509Certificate2 and contains the private key.
System.Net Information: 0 : [8960] SecureChannel#2781196::.AcquireClientCredentials, new SecureCredential() (flags=(ValidateManual, NoDefaultCred, SendAuxRecord, UseStrongCrypto), m_ProtocolFlags=(Tls13Client), m_EncryptionPolicy=RequireEncryption)
System.Net Information: 0 : [8960] AcquireCredentialsHandle(package = Microsoft Unified Security Protocol Provider, intent  = Outbound, scc     = System.Net.SecureCredential2)
System.Net Information: 0 : [8960] InitializeSecurityContext(credential = System.Net.SafeFreeCredential_SECURITY, context = 2386dfb1ac0:20fdc0e8ce0, targetName = api.ibanity.com, inFlags = ReplayDetect, SequenceDetect, Confidentiality, AllocateMemory, InitManualCredValidation)
System.Net Information: 0 : [8960] InitializeSecurityContext(In-Buffers count=2, Out-Buffer length=3208, returned code=OK).
System.Net Information: 0 : [8960] Remote certificate:
< /code>
Я не понимаю, почему он терпит неудачу в первый раз после нового начала веб -сервера, но затем он работает нормально. Мы изучали это более недели. Если мы каждый раз раскручиваем новый httpclient, код работает после второго запуска. Мы попытались использовать именованный httpclient 
, попытались использовать метод ihttpfactory и т. Д. Таким образом, в экземпляре Singleton мы повторно используем этот первый httpclient , и код всегда сбой на производственном сервере (не в поле разработчиков). При включении второго httpclient (из одного и того же httphandler ) код работает, также на производственном сервере.

Подробнее здесь: https://stackoverflow.com/questions/796 ... in-net-4-8
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»