【问题标题】:CryptographicException Bad Key when trying to load public key into RSACryptoServiceProvider尝试将公钥加载到 RSACryptoServiceProvider 时出现 CryptographicException Bad Key
【发布时间】:2021-08-06 20:22:48
【问题描述】:

我不确定这个问题是如何发生的,我试图传递给 CSP 的密钥最初是一个 Base64Encoded 字符串,我也尝试使用 ImportSubjectInfoKey() 传递它。每次调试时,我都导出了参数,并且我能够将我的公钥作为 Base64 字符串取回,据我所知它是一个有效的密钥。但是,一旦它遇到了 VerifyData 方法,它就会因 Bad Key 异常而中断。在调试时,我确实注意到 rsa1.CspKeyContainerInfo 提到了一个错误“可导出:{key 不存在}”。这是我的问题的来源吗?如果有人能看到问题,我已将下面的公钥作为 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 

【问题讨论】:

    标签: c# .net-core cryptography rsa blazor


    【解决方案1】:

    发布的代码失败,因为 VerifySignature() 不期望原始数据,而是 散列 数据,另请参阅文档中的 this example

    进行以下更改:

    var paymentTokenAsBytes = SHA256.Create().ComputeHash(Encoding.UTF8.GetBytes(paymentToken));
    

    验证成功。


    如果密钥以 X.509/SPKI 格式(DER 编码)可用,也可以使用 ImportSubjectPublicKeyInfo() 导入。对于验证,可以交替使用方法VerifyData()(隐式哈希数据)和VerifyHash()(期望已经哈希的数据)。

    【讨论】:

    • 非常感谢!我已经为此苦苦挣扎了一段时间,现在你真的帮助了我!不敢相信我是如此接近,以至于我多次重写了我的关键部分,因为我认为就是这样。再次感谢:)
    猜你喜欢
    • 1970-01-01
    • 2017-10-07
    • 2014-04-30
    • 2016-05-28
    • 2021-06-13
    • 1970-01-01
    • 2016-08-16
    • 1970-01-01
    相关资源
    最近更新 更多