尝试将 public 密钥加载到 RSACryptoServiceProvider 时出现 CryptographicException Bad Key
CryptographicException Bad Key when trying to load public key into RSACryptoServiceProvider
我不确定这个问题是怎么发生的,我试图传递给 CSP 的密钥最初是一个 Base64Encoded 字符串,我也尝试使用 ImportSubjectInfoKey() 传递它。每次调试时,我都导出了参数,并且我能够将我的 public 密钥作为 Base64 字符串取回,据我所知它是一个有效密钥。但是,一旦它遇到 VerifyData 方法,它就会因 Bad Key 异常而中断。在调试时,我确实注意到 rsa1.CspKeyContainerInfo 提到了一个错误“可导出:{key 不存在}”。这是我的问题的来源吗?如果有人能看到问题,我将下面的 public 键作为 XML 字符串包含在内。
private static bool VerifyData(string paymentToken, string signature)
{
var rsa1 = new RSACryptoServiceProvider(2048);
string publicKey = @"
<RSAKeyValue><Modulus>zIU140G9rFe6ouNFuhCxIj3Ps3ELUV9w4XTnDsti8kcSTXMf0z6LMNVIqXaZYFbSYXAZRmuM3XNmoSWmMZzPBMl2/C7uC0wyNdrYdPw0uzU2wfr8MQbnvW0yQgQ/cSHNDUZR+n/s2ipXTdNmbRd4z+k+qXxw00xMDmiJu5iMHyYo24x284lTZ3+4dgL4xFlrtjgcb/NGHBpVPQTCbBfEQcmylCwzbTUdBJlAo5ezpziOJ6CNf9FDS1hvRKRvNl7Hx8To6vQZJTwdCT5RWDC2JYL0oSdPV+SZmlfHQQe33p81MiRl4cjp5AwMVKyAosDihGT810WFYhK431EIB/NR/w==</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>";
rsa1.FromXmlString(publicKey);
// Converts back to my original Base64 encoded public key so it seems valid.
var x = rsa1.ExportSubjectPublicKeyInfo();
var a = Convert.ToBase64String(x);
RSAPKCS1SignatureDeformatter rsaDeformatter = new(rsa1);
rsaDeformatter.SetHashAlgorithm("SHA256");
var paymentTokenAsBytes = Encoding.UTF8.GetBytes(paymentToken);
var signatureAsBytes = Convert.FromBase64String(signature);
bool verified = false;
try
{
if (rsaDeformatter.VerifySignature(paymentTokenAsBytes, signatureAsBytes))
{
Console.WriteLine("The signature is valid.");
verified = true;
}
else
{
Console.WriteLine("The signature is not valid.");
verified = false;
}
} catch(CryptographicException ex)
{
Debug.WriteLine($"What is going on!! {ex} ");
}
return verified;
错误:
Internal.Cryptography.CryptoThrowHelper+WindowsCryptographicException: Bad Key.
at Internal.NativeCrypto.CapiHelper.CreateHashHandle(SafeProvHandle hProv, Byte[] hash, Int32
calgHash)
at Internal.NativeCrypto.CapiHelper.VerifySign(SafeProvHandle hProv, SafeKeyHandle hKey, Int32
calgKey, Int32 calgHash, Byte[] hash, Byte[] signature)
at System.Security.Cryptography.RSACryptoServiceProvider.VerifyHash(Byte[] hash, Byte[] signature,
HashAlgorithmName hashAlgorithm, RSASignaturePadding padding)
at System.Security.Cryptography.RSAPKCS1SignatureDeformatter.VerifySignature(Byte[] rgbHash, Byte[]
rgbSignature)
at Go.Server.Controllers.CitizenWebhook.VerifyData(String paymentToken, String signature) in
C:\Users\Dylan\source\repos\GO5050PLATFORM\Go\Server\Controllers\Webhooks\CitizenWebhook.cs:line 108
发布的代码失败,因为 VerifySignature()
doesn't expect the raw data but the hashed data, see also this example 来自文档。
具有以下更改:
var paymentTokenAsBytes = SHA256.Create().ComputeHash(Encoding.UTF8.GetBytes(paymentToken));
验证成功
如果密钥以 X.509/SPKI 格式(DER 编码)提供,也可以使用 ImportSubjectPublicKeyInfo()
. For verification, the methods VerifyData()
(hashes the data implicitly) and VerifyHash()
导入(期望已经散列的数据)也可以使用。
我不确定这个问题是怎么发生的,我试图传递给 CSP 的密钥最初是一个 Base64Encoded 字符串,我也尝试使用 ImportSubjectInfoKey() 传递它。每次调试时,我都导出了参数,并且我能够将我的 public 密钥作为 Base64 字符串取回,据我所知它是一个有效密钥。但是,一旦它遇到 VerifyData 方法,它就会因 Bad Key 异常而中断。在调试时,我确实注意到 rsa1.CspKeyContainerInfo 提到了一个错误“可导出:{key 不存在}”。这是我的问题的来源吗?如果有人能看到问题,我将下面的 public 键作为 XML 字符串包含在内。
private static bool VerifyData(string paymentToken, string signature)
{
var rsa1 = new RSACryptoServiceProvider(2048);
string publicKey = @"
<RSAKeyValue><Modulus>zIU140G9rFe6ouNFuhCxIj3Ps3ELUV9w4XTnDsti8kcSTXMf0z6LMNVIqXaZYFbSYXAZRmuM3XNmoSWmMZzPBMl2/C7uC0wyNdrYdPw0uzU2wfr8MQbnvW0yQgQ/cSHNDUZR+n/s2ipXTdNmbRd4z+k+qXxw00xMDmiJu5iMHyYo24x284lTZ3+4dgL4xFlrtjgcb/NGHBpVPQTCbBfEQcmylCwzbTUdBJlAo5ezpziOJ6CNf9FDS1hvRKRvNl7Hx8To6vQZJTwdCT5RWDC2JYL0oSdPV+SZmlfHQQe33p81MiRl4cjp5AwMVKyAosDihGT810WFYhK431EIB/NR/w==</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>";
rsa1.FromXmlString(publicKey);
// Converts back to my original Base64 encoded public key so it seems valid.
var x = rsa1.ExportSubjectPublicKeyInfo();
var a = Convert.ToBase64String(x);
RSAPKCS1SignatureDeformatter rsaDeformatter = new(rsa1);
rsaDeformatter.SetHashAlgorithm("SHA256");
var paymentTokenAsBytes = Encoding.UTF8.GetBytes(paymentToken);
var signatureAsBytes = Convert.FromBase64String(signature);
bool verified = false;
try
{
if (rsaDeformatter.VerifySignature(paymentTokenAsBytes, signatureAsBytes))
{
Console.WriteLine("The signature is valid.");
verified = true;
}
else
{
Console.WriteLine("The signature is not valid.");
verified = false;
}
} catch(CryptographicException ex)
{
Debug.WriteLine($"What is going on!! {ex} ");
}
return verified;
错误:
Internal.Cryptography.CryptoThrowHelper+WindowsCryptographicException: Bad Key.
at Internal.NativeCrypto.CapiHelper.CreateHashHandle(SafeProvHandle hProv, Byte[] hash, Int32
calgHash)
at Internal.NativeCrypto.CapiHelper.VerifySign(SafeProvHandle hProv, SafeKeyHandle hKey, Int32
calgKey, Int32 calgHash, Byte[] hash, Byte[] signature)
at System.Security.Cryptography.RSACryptoServiceProvider.VerifyHash(Byte[] hash, Byte[] signature,
HashAlgorithmName hashAlgorithm, RSASignaturePadding padding)
at System.Security.Cryptography.RSAPKCS1SignatureDeformatter.VerifySignature(Byte[] rgbHash, Byte[]
rgbSignature)
at Go.Server.Controllers.CitizenWebhook.VerifyData(String paymentToken, String signature) in
C:\Users\Dylan\source\repos\GO5050PLATFORM\Go\Server\Controllers\Webhooks\CitizenWebhook.cs:line 108
发布的代码失败,因为 VerifySignature()
doesn't expect the raw data but the hashed data, see also this example 来自文档。
具有以下更改:
var paymentTokenAsBytes = SHA256.Create().ComputeHash(Encoding.UTF8.GetBytes(paymentToken));
验证成功
如果密钥以 X.509/SPKI 格式(DER 编码)提供,也可以使用 ImportSubjectPublicKeyInfo()
. For verification, the methods VerifyData()
(hashes the data implicitly) and VerifyHash()
导入(期望已经散列的数据)也可以使用。