0

我需要为不支持 SHA256 的旧旧系统生成 SHA1 哈希证书。我很清楚不建议在加密场景中使用 MD5 和 SHA1 哈希,但这是一个外部要求。

我正在使用 .NET Framework 4.7.2 及其新的CertificateRequest类。

这是相关的代码片段:

            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()

从我正在使用的构造函数的.NET API 浏览器中,即使不推荐,我也看不出为什么这不起作用。使用 MD5 会引发类似的异常。SHA256 及更高版本工作正常。

该类CertificateRequest也没有显示在参考源中(可能是因为它太新了?)所以我没有想法。

4

1 回答 1

0

不支持 MD5 和 SHA-1 是故意的,基于功能拉取请求的反馈(打开链接后,您必须等待几秒钟,而页面加载足够的代码以找到锚点然后重新跳转)。

该文档现已更新为:

评论

此方法不支持使用 MD5 或 SHA-1 作为证书签名的哈希算法。如果您需要基于 MD5 或 SHA-1 的证书签名,则需要实现自定义 X509SignatureGenerator 并调用 Create(X500DistinguishedName, X509SignatureGenerator, DateTimeOffset, DateTimeOffset, Byte[])。

创建 X509SignatureGenerator 肯定很难,对吧?好吧,来自同一个反馈链接:

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); 
} 

该代码还用于测试提供自定义生成器的能力。

于 2020-01-30T15:58:59.427 回答