3

我已经使用 RSACryptoServiceProvider 加密了一个文本。我导出了公钥和私钥。显然我只是想在解码器应用程序中公开公钥,所以我编写了如下代码:

private const string PublicKey = "<RSAKeyValue><Modulus>sIzQmj4vqK0QPd7RXKigD7Oi4GKPwvIPoiUyiKJMGP0qcbUkRPioe2psE/d3c1a2NY9oj4Da2y1qetjvKKFad2QAhXuql/gPIb1WmI+f6q555GClvHWEjrJrD/ho7SLoHbWd6oY6fY609N28lWJUYO97RLVaeg2jfNAUSu5bGC8=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>";

private string Decrypt()
        {
            byte[] encryptedKeyAsBytes = Convert.FromBase64String(_encryptedKey);
            RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
            rsa.FromXmlString(PublicKey);
            // read ciphertext, decrypt it to plaintext
            byte[] plainBytes = rsa.Decrypt(encryptedKeyAsBytes, false);
            string plainText = System.Text.Encoding.ASCII.GetString(plainBytes);

            return plainText;
        }

但在“byte[] plainBytes = rsa.Decrypt(encryptedKeyAsBytes, false);”行抛出异常 并说“钥匙不存在”。但是,如果我公开整个私钥和公钥,那么它会运行得很愉快。那么如何仅使用公钥信息解密数据呢?

4

3 回答 3

6

你不能——这就是公钥/私钥加密的重点。公众进行加密;私人进行解密。

听起来您需要某种密钥交换模式。例如; 如果您的解码器应用程序试图从另一个数据源(源应用程序)解密信息,我会实现这样的事情:

  1. 源应用程序生成一个对称密钥,如 AES。
  2. 解码器应用程序生成一个公钥和私钥对。
  3. 源应用程序向解码器应用程序询问公钥。
  4. 源应用程序使用公钥加密对称密钥,并将其发送回解码器应用程序。
  5. 解码器应用程序使用私钥来解密对称密钥。
  6. 解码器应用程序从源应用程序获取使用对称密钥加密的数据。
  7. 解码器应用程序使用交换的对称密钥来解密它收到的信息。

这只是一个例子;但说明了如何在两个应用程序之间交换数据而无需通过网络传输任何敏感信息的基础知识。根本不需要对称密钥;但这是一种非常常见的模式,因为 RSA 在加密大量信息时开始引入问题。RSA 最好只加密对称加密密钥。

于 2011-07-20T14:56:20.687 回答
5

简短的回答是:你不能。要解密消息,您需要私钥,这是非对称密码学的主要原则。

您使用某人的公钥加密消息,以便只有拥有相应私钥的人才能解密它们。

这就是为什么公钥被称为公开的 - 您可以安全地将其分发给公众,以便他们可以加密消息以供您作为相应私钥的唯一所有者阅读。

于 2011-07-20T14:51:13.007 回答
2

问题是您混淆了加密和签名。

加密是任何人都可以消息的地方,但只有私钥持有者可以读取它。签名是任何人都可以阅读消息的地方,但只有私钥持有者可以编写它。

当你调用 Decrypt 时,RSACryptoServiceProvider 正在寻找加密,即公写私有读。因此它寻找私钥。

您想使用 SignData 和 VerifyData 函数对有效负载进行签名,这样人们就无法编写它。

于 2016-08-30T12:33:29.113 回答