解密 RSA 签名哈希时出现 NotImplementedException

NotImplementedException when decrypting RSA signed hash

我想在 UWP 应用程序中使用 CryptographicEngine 验证 私钥签名的 SHA256 哈希 。哈希是在外部创建的,并使用带有密码的 RSA 私钥进行签名。然而,对于这个例子,我还生成了未签名的散列。然后在最后比较两个哈希值以验证它们是否相同。

我使用 OSX 命令行创建了我的私钥和 public 密钥,在 this blog 中指定。

这给了我两个 .pem 文件。我的 public 密钥具有以下结构:

-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3fasaNKpXDf4B4ObQ76X
qOaSRaedFCAHvsW4G0PzxL/...ETC ETC
-----END PUBLIC KEY-----

这是我用来解密哈希的 C# 代码:

        //HASH THE INPUT STRING
        var inputText = "stringtohash";

        // put the string in a buffer, UTF-8 encoded...
        IBuffer input = CryptographicBuffer.ConvertStringToBinary(inputText,
            BinaryStringEncoding.Utf8);

        // hash it...
        var hasher = HashAlgorithmProvider.OpenAlgorithm("SHA256");

        IBuffer hashed = hasher.HashData(input);

        // format it...
        string ourhash = CryptographicBuffer.EncodeToBase64String(hashed);

        Debug.WriteLine(ourhash);

        //CONVERT EXTERNAL HASH TO BUFFER
        IBuffer data = CryptographicBuffer.DecodeFromBase64String("b18fbf9bc0fc7595af646155e18b71e1aeccf01719f9f293c72217d7b95cc2106edb419078c4c5c1c7f7d106b90198a4f26beb49ff4a714db4bface1f94fff193b8126ce05fe13825144a3dde97f55399846b6fd768f1fb152f1ba71bbf5cde8c1a7e58621a493070256e2444db36c346a88e870906529cf13c072ead50b6a01b2e74c7ef8c5d423e8ea25220f524b563ae2c3345b7837f9cd1a357540b1380c86287b9a240cf67f7518f11418352b665b657c5ffb6cbcb6126ec59e360de6304392b78cf4de79b52d73b8292df6a1e643d0c0f0945aae5949b391e2915772c996f03e6d1879192b7edf0f40c01b875e768358aa47a992070f628418ddf06472");

        //CONVERT PUBLIC KEY TO BUFFER
        IBuffer publickey = CryptographicBuffer.DecodeFromBase64String("MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3fasaNKpXDf4B4ObQ76XqOaSRaedFCAHvsW4G0PzxL / RuAQFz80esZPyyDCps1PAbTKzQ + QblChPo7PJkbsU4HzNN4PIRGh5xum6SRmdvOowrlTUtyxdOkRJoFxmiR / VCea + PUspt26F7PLcK9ao5 + hVzMvPuqdYenqzd01f1t5hQEhFQ9qjB6Es8fpizHd / RSRfZ7n6rVKm9wYfCRLB7GJ7IHhWGuZrx9fjzsbW8eagu06qRhnUuR5oDVjXC8ZeazsRiw50xMuOzkhX9Oo081IYikwCgseJmQhT7vF4lZoyeB4qJpwTCA + glSy1w9N8ZfxyXK8QaT2RsrBrzl0ZCwIDAQAB");

        // Open an asymmetric algorithm provider for the specified algorithm. 
        AsymmetricKeyAlgorithmProvider rsa = AsymmetricKeyAlgorithmProvider.OpenAlgorithm(AsymmetricAlgorithmNames.RsaPkcs1);

        // Import Key
        CryptographicKey key =  rsa.ImportPublicKey(publickey, CryptographicPublicKeyBlobType.X509SubjectPublicKeyInfo);

        // Decrypt the Hash using our Key
        IBuffer result = CryptographicEngine.Decrypt(key, data, null);

        Debug.WriteLine(result.ToString());

        //Compare the two hashes

        if (data == result) {

            //Hash is verified!
        }

不幸的是,当到达 Decrypt 方法时,我得到一个 NotImplementedException 错误

The method or operation is not implemented

我在网上进行了研究,我明白理论上需要发生什么,但我不知道如何进一步调试。我可以尝试什么?

虽然都叫PKCS#1 v1.5 padding,但是签名生成和加密的padding 不一样,见RFC 3447了解更多详情。

如果你看一下the RsaPkcs1 property,你会发现它是针对加密的:

Use the string retrieved by this property to set the asymmetric algorithm name when you call the OpenAlgorithm method. The string represents an RSA public key algorithm that uses PKCS1 to pad the plaintext. No hash algorithm is used.

因为我没有看到“原始 RSA”的任何选项,即没有填充的 RSA,看来您只能验证您的签名。但是,RSA 解密需要一个 RSA 私钥。您很可能因此而收到错误:如果您尝试使用 public 密钥解密,它将失败。

如果你想预先计算哈希值,你可以使用 VerifySignatureWithHashInput.

对于其他功能,您可能需要使用例如Bouncy Castle 的 C# 轻量级 API。最后,您不需要平台提供的密码来验证签名。