创建rsa-sha512签名时算法无效

时间:2018-04-30 08:24:33

标签: c# .net cryptography digital-signature

我正在尝试使用本地HDD上的证书将rsa-sha512签名应用于邮件。 最终的SignData会引发加密异常“指定的无效算法”。 但是,如果我在RSACryptoServiceProvider的新实例上使用SignData(通过导入原始RSACryptoServiceProvider的导出创建),我不会得到该异常。 是否有某些原因导致原始版本引发异常?由于“副本”明显不同,我宁愿使用原件。

我正在使用的c#代码如下:

X509Certificate2 cert = new X509Certificate2("C:\\Certs\\" + certName + ".p12", certPassword, X509KeyStorageFlags.Exportable);
RSACryptoServiceProvider csp = (RSACryptoServiceProvider)cert.PrivateKey;
UTF8Encoding ByteConverter = new UTF8Encoding();
byte[] unsignedBytes = ByteConverter.GetBytes(unsignedText);
byte[] signature;

//This raises an exception, "Invalid algorithm specified."
signature = csp.SignData(unsignedBytes, new SHA512CryptoServiceProvider());

//But if I make a copy of the RSACryptoServiceProvider, no exception is raised
RSACryptoServiceProvider cspCopy = new RSACryptoServiceProvider();
RSAParameters Key = csp.ExportParameters(true);
cspCopy.ImportParameters(Key);
signature = cspCopy.SignData(unsignedBytes, new SHA512CryptoServiceProvider());

1 个答案:

答案 0 :(得分:0)

a previous answer引用自己:

  

当CSP ProviderType值为24(PROV_RSA_AES)且ProviderName为“Microsoft Enhanced RSA and AES Cryptographic Provider”(MS_ENH_RSA_AES_PROV)时,软件支持的RSACryptoServiceProvider只能使用SHA-2摘要算法执行RSA签名。硬件可能需要也可能不需要PROV_RSA_AES,仅取决于硬件。

在这种情况下,PFX识别属于旧CSP的私钥(或者,它可能没有CSP标识符,PFX导入正在选择错误的默认值)。对于软件密钥,可以从密钥中提取CspParameterInfo数据,并使用ProviderType 24重新打开它,这是解决问题的一种方法。导出原始RSA参数并将其导入新对象(默认为ProviderType 24)是一种更具侵略性的解决方法。

解决此问题的更好方法是放弃RSACryptoServiceProvider。不使用cert.PrivateKey,而是使用cert.GetRSAPrivateKey(),它几​​乎总会返回一个没有此问题的RSACng实例(但是如果你可以避免它就不要强制转换它(如果没有别的话,请参阅“几乎”总是))。

byte[] signature;

using (RSA rsa = cert.GetRSAPrivateKey())
{
    signature = rsa.SignData(
        unsignedBytes,
        HashAlgorithmName.SHA512,
        RSASignaturePadding.Pkcs1);
}

using语句对于GetRSAPrivateKey是正确的,因为它会为每次调用返回一个不同的对象。

RSACng和GetRSAPrivateKey都需要.NET 4.6,但此时已经超过两年了(并且在那段时间内发生了4(半)个新版本),所以不应该因为依赖而导致困难。