ArgumentOutOfRangeException при попытке создать самозаверяющий сертификат с помощью CertificateRequest с SHA1 в. NET 4.7.2 - PullRequest
0 голосов
/ 23 января 2020

У меня есть требование генерировать хэшированные сертификаты SHA1 для старой устаревшей системы, которая не поддерживает SHA256. Я хорошо знаю, что хеширование MD5 и SHA1 в криптосценарии ios не рекомендуется, но это внешнее требование.

Я использую. NET Framework 4.7.2 и его новый CertificateRequest class.

Вот соответствующий фрагмент кода:

            using (var rsa = RSA.Create(2048))
            {
                var subjectName = "CN=sampleName";
                var certificateRequest = new CertificateRequest(subjectName, rsa, HashAlgorithmName.SHA1, RSASignaturePadding.Pkcs1);
                var selfSignedCertificate = certificateRequest.CreateSelfSigned(DateTime.UtcNow, DateTime.UtcNow.AddYears(10));
                var certAsBytes = selfSignedCertificate.Export(X509ContentType.Pfx, "fakePassword");
                File.WriteAllBytes("cert-sha1.pfx", certAsBytes);
            }

При вызове certificateRequest.CreateSelfSigned выдается следующее исключение:

'SHA1' is not a known hash algorithm.
Parameter name: hashAlgorithm
Actual value was SHA1.

Соответствующая точка в трассировке стека:

...
   at System.Security.Cryptography.X509Certificates.RSAPkcs1X509SignatureGenerator.GetSignatureAlgorithmIdentifier(HashAlgorithmName hashAlgorithm)
   at System.Security.Cryptography.X509Certificates.TbsCertificate.Encode(X509SignatureGenerator signatureGenerator, HashAlgorithmName hashAlgorithm)
   at System.Security.Cryptography.X509Certificates.TbsCertificate.Sign(X509SignatureGenerator signatureGenerator, HashAlgorithmName hashAlgorithm)
   at System.Security.Cryptography.X509Certificates.CertificateRequest.Create(X500DistinguishedName issuerName, X509SignatureGenerator generator, DateTimeOffset notBefore, DateTimeOffset notAfter, Byte[] serialNumber)
   at System.Security.Cryptography.X509Certificates.CertificateRequest.CreateSelfSigned(DateTimeOffset notBefore, DateTimeOffset notAfter)
   at Tests.Sha1Test()

Из браузера API . NET для конструктора, который я использую, я не вижу ничего, почему это не следует не работает, даже если не рекомендуется. Использование MD5 создает похожее исключение. SHA256 и выше работают нормально.

Класс CertificateRequest также не отображается в справочном источнике (может быть, потому что он слишком новый?), Поэтому у меня нет идей.

1 Ответ

0 голосов
/ 30 января 2020

Не поддерживал MD5 и SHA-1 был преднамеренным, на основе обратной связи от запроса на выборку функции (после открытия ссылки вам придется подождать несколько секунд, пока страница загружает достаточно кода, чтобы найти привязку, а затем повторный переход).

Документация была обновлена, чтобы сказать, что:

Замечания

Этот метод не поддерживает использование MD5 или SHA-1 в качестве алгоритма ha sh для подписи сертификата. Если вам нужна подпись сертификата на основе MD5 или SHA-1, вам нужно реализовать пользовательский X509SignatureGenerator и вызвать Create (X500DistinguishedName, X509SignatureGenerator, DateTimeOffset, DateTimeOffset, Byte []).

Конечно, создание X509Signature сложно, правда? Ну, по той же ссылке обратной связи:

private sealed class RSASha1Pkcs1SignatureGenerator : X509SignatureGenerator 
{ 
     private readonly X509SignatureGenerator _realRsaGenerator; 

     internal RSASha1Pkcs1SignatureGenerator(RSA rsa) 
     { 
         _realRsaGenerator = X509SignatureGenerator.CreateForRSA(rsa, RSASignaturePadding.Pkcs1); 
     } 

     protected override PublicKey BuildPublicKey() => _realRsaGenerator.PublicKey; 

     public override byte[] GetSignatureAlgorithmIdentifier(HashAlgorithmName hashAlgorithm) 
     { 
         if (hashAlgorithm == HashAlgorithmName.SHA1) 
             return "300D06092A864886F70D0101050500".HexToByteArray(); 

         throw new InvalidOperationException(); 
     } 

     public override byte[] SignData(byte[] data, HashAlgorithmName hashAlgorithm) => 
         _realRsaGenerator.SignData(data, hashAlgorithm); 
} 

Этот код также используется в качестве теста на возможность предоставления собственного генератора.

...