解密 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。最后,您不需要平台提供的密码来验证签名。
我想在 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。最后,您不需要平台提供的密码来验证签名。