C# 加密例外情况:';指定的算法无效';使用SHA-512时
在我的WPF应用程序(.NET 4.6)中,我需要使用P12证书文件使用SHA-512算法对字符串进行签名(包括在web请求的头中)。我的发言如下:C# 加密例外情况:';指定的算法无效';使用SHA-512时,c#,.net,windows,x509certificate2,sha512,C#,.net,Windows,X509certificate2,Sha512,在我的WPF应用程序(.NET 4.6)中,我需要使用P12证书文件使用SHA-512算法对字符串进行签名(包括在web请求的头中)。我的发言如下: using (var rsa = myX509Certificate2.GetRSAPrivateKey()) { myBytes = rsa.SignData( Encoding.UTF8.GetBytes(stringToSign), HashAlgorithmName.SHA512, RSASignatureP
using (var rsa = myX509Certificate2.GetRSAPrivateKey()) {
myBytes = rsa.SignData(
Encoding.UTF8.GetBytes(stringToSign),
HashAlgorithmName.SHA512,
RSASignaturePadding.Pkcs1
);
}
这适用于测试和几乎所有我的客户,但奇怪的客户得到以下例外:
System.Security.Cryptography.CryptographicException: Invalid algorithm specified.
at System.Security.Cryptography.CryptographicException.ThrowCryptographicException(Int32 hr)
at System.Security.Cryptography.Utils.SignValue(SafeKeyHandle hKey, Int32 keyNumber, Int32 calgKey, Int32 calgHash, Byte[] hash, Int32 cbHash, ObjectHandleOnStack retSignature)
at System.Security.Cryptography.Utils.SignValue(SafeKeyHandle hKey, Int32 keyNumber, Int32 calgKey, Int32 calgHash, Byte[] hash)
at System.Security.Cryptography.RSACryptoServiceProvider.SignHash(Byte[] rgbHash, Int32 calgHash)
at System.Security.Cryptography.RSACryptoServiceProvider.SignHash(Byte[] hash, HashAlgorithmName hashAlgorithm, RSASignaturePadding padding)
at System.Security.Cryptography.RSA.SignData(Byte[] data, Int32 offset, Int32 count, HashAlgorithmName hashAlgorithm, RSASignaturePadding padding)
at System.Security.Cryptography.RSA.SignData(Byte[] data, HashAlgorithmName hashAlgorithm, RSASignaturePadding padding)
最近发生在Windows7SP1上的一位客户身上
我正努力通过现有的SO问题或从谷歌那里找到答案。据我所知,这可能是由于一个不受支持的Windows加密服务提供商在幕后使用,但我不确定,因为我自己无法复制错误
如果您使用的是
cert.GetRSAPrivateKey()
,并且它返回了一个RSACryptoServiceProvider
实例,该实例表明它不是来自PFX,而是来自一个带有旧驱动程序的智能卡,那么您有什么办法解决这个问题吗。既然你说它来自于一个.p12/.pfx,那么pfx可能包含了一个对CNG没有接管的常用加密服务提供商名称的引用(但我从未在软件密钥中看到)。(奥卡姆的剃须刀让人不禁要问:你确定他们不是无意中使用了错误的证书吗?)
如果您知道它来自PFX,并且已使用可导出位导入它,则可以手动将其从RSACryptServiceProvider转换为RSACng:
using (RSA rsa = cert.GetRSAPrivateKey())
{
byte[] toSign = Encoding.UTF8.GetBytes(stringToSign);
myBytes = null;
try
{
myBytes = rsa.SignData(
toSign,
HashAlgorithmName.SHA512,
RSASignaturePadding.Pkcs1);
}
catch (CryptographicException)
{
try
{
using (RSA rsaCng = new RSACng())
{
rsaCng.ImportParameters(rsa.ExportParameters(true));
myBytes = rsaCng.SignData(
toSign,
HashAlgorithmName.SHA512,
RSASignaturePadding.Pkcs1);
}
}
catch
{
}
if (myBytes == null)
{
// Let the original exception continue
throw;
}
}
}
(作为原始异常抛出的替代方法,您可以决定让“重试”异常抛出)
或者,Windows 10修复了许多RSACryptoServiceProvider的“无效算法”行为,因此他们可以随时尝试升级。谢谢–我将对此进行构建,并让客户试用。