当使用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
来重现异常。
我最终通过使用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();
}
}