当使用iTextSharp和RSA和AES csp时,提供程序类型不匹配注册值

本文关键字:程序 类型 注册 不匹配 iTextSharp RSA csp AES | 更新日期: 2023-09-27 18:17:01

我想使用SHA-256作为哈希算法使PADES签名成为PDF。我使用下面的代码:

public static byte[] Sign(
    byte[] pdfIn,
    X509Certificate2 cert,
    string reason,
    string hashAlgorithm = DigestAlgorithms.SHA1
    )
{
    using (var reader = new PdfReader(pdfIn))
    using (var pdfOut = new MemoryStream())
    {
        var stamper = PdfAStamper.CreateSignature(reader, pdfOut, ''0');
        var appearance = stamper.SignatureAppearance;
        appearance.Reason = reason;          
        var parser = new X509.X509CertificateParser();
        var chain = new X509.X509Certificate[] { 
            parser.ReadCertificate(cert.RawData)
        };
        var signature = new X509Certificate2Signature(cert, hashAlgorithm);
        MakeSignature.SignDetached(
            appearance,
            signature,
            chain,
            null,
            null,
            null,
            0,
            CryptoStandard.CADES
            );
        return pdfOut.ToArray();          
    }
}

我正在用certutil导入证书。如果我使用以下命令并使用SHA-1作为哈希算法,它可以正常工作:

certutil -f -user -p PASSWORD -importpfx CERT_NAME.pfx

但是如果我选择具有SHA-256功能的csp,我将得到CryptographicException, provider type does not match registered value。导入是通过:

certutil -f -user -p PASSWORD -csp "Microsoft Enhanced RSA and AES Cryptographic Provider" -importpfx CERT_NAME.pfx

例外是:

Result Message: System.Security.Cryptography.CryptographicException : provider type does not match registered value
Result StackTrace:  
in System.Security.Cryptography.Utils.CreateProvHandle(CspParameters parameters, Boolean randomKeyContainer)
   in System.Security.Cryptography.Utils.GetKeyPairHelper(CspAlgorithmType keyType, CspParameters parameters, Boolean randomKeyContainer, Int32 dwKeySize, SafeProvHandle& safeProvHandle, SafeKeyHandle& safeKeyHandle)
   in System.Security.Cryptography.RSACryptoServiceProvider.GetKeyPair()
   in System.Security.Cryptography.RSACryptoServiceProvider..ctor(Int32 dwKeySize, CspParameters parameters, Boolean useDefaultKeySize)
   in System.Security.Cryptography.X509Certificates.X509Certificate2.get_PrivateKey()
   in iTextSharp.text.pdf.security.X509Certificate2Signature..ctor(X509Certificate2 certificate, String hashAlgorithm)
   in PdfCommon.Pdf.Sign(Byte[] pdfIn, X509Certificate2 cert, String reason, String hashAlgorithm) in c:'Projects'svn'playground'trunk'PdfCommon'Pdf.cs:line 46
   in PdfCommon.Tests.Pdf_test.Should_sign_a_pdf_with_pades_basic_profile() in c:'Projects'svn'playground'trunk'PdfCommon.Tests'Pdf_test.cs:line 54

检索私钥时抛出异常。我可以通过访问cert.PrivateKey来重现异常。

当使用iTextSharp和RSA和AES csp时,提供程序类型不匹配注册值

我最终通过使用RSACryptoServiceProvider来检索私钥来解决这个问题:

    public static byte[] Sign(
        byte[] pdfIn,
        X509Certificate2 cert,
        string reason = "",
        string hashAlgorithm = DigestAlgorithms.SHA256
        )
    {
        using (var reader = new PdfReader(pdfIn))
        using (var pdfOut = new MemoryStream())
        using (var rsa = (RSACryptoServiceProvider)cert.PrivateKey)
        {
            var stamper = PdfAStamper.CreateSignature(reader, pdfOut, ''0');
            var appearance = stamper.SignatureAppearance;
            appearance.Reason = reason;
            var signature = new PrivateKeySignature(
                DotNetUtilities.GetRsaKeyPair(rsa).Private,
                hashAlgorithm);
            var parser = new X509.X509CertificateParser();
            var chain = new X509.X509Certificate[] { 
            parser.ReadCertificate(cert.RawData)
            };
            MakeSignature.SignDetached(
                appearance,
                signature,
                chain,
                null,
                null,
                null,
                0,
                CryptoStandard.CADES
                );
            return pdfOut.ToArray();
        }
    }