使用 iTextSharp、RSA 和 AES csp 时,CryptographicException,提供者类型与注册值不匹配
CryptographicException, provider type does not match registered value, when using iTextSharp and RSA and AES csp
我想使用 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, '[=10=]');
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
作为 hashAlgorithm,它可以正常工作:
certutil -f -user -p PASSWORD -importpfx CERT_NAME.pfx
但是如果我 select 具有 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, '[=10=]');
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();
}
}
我想使用 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, '[=10=]');
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
作为 hashAlgorithm,它可以正常工作:
certutil -f -user -p PASSWORD -importpfx CERT_NAME.pfx
但是如果我 select 具有 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, '[=10=]');
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();
}
}