使用 RSACryptoServiceProvider 解密失败

Decryption with RSACryptoServiceProvider fails

我想解密一个字节数组。为此,我使用服务器 public 密钥对 java 中的数据进行加密。然后我将数据发送到 c# 服务器。我想用“RSACryptoServiceProvider”class 解密。我初始化它:

RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(1024);
rsa.ImportParameters(keyInfo);

“keyInfo”(RSAParameters) 变量用“modulus”和“privateKey”初始化

keyInfo.Modulus = m.getBytes();
keyInfo.D = d.getBytes();

“m”和“d”的值是硬编码的,来自 here 的 BigInteger 实例。我知道硬编码不好,但目前我可以这样做。

当我这样做时,抛出异常“错误数据”。当我在

中添加 public 键时

keyInfo.Exponent = pubExpBytes

然后就通过了,但是稍后在方法中抛出异常"Key does not exist"

result = rsa.Decrypt(inputBuf, false);

并且 属性“PublicOnly”为真,即使我在“keyInfo.D”中添加了密钥。

我做错了什么?

使用RSACryptoServiceProvider时私钥由Modulus、Exponent、P、Q、DP、DQ、InverseQ、D组成,待设置。最好从 xml 字符串加载密钥,例如:

string xmlKey = "<RSAKeyValue><Modulus>2CASUiCNfcCc/Y2gCJwmUPc1VWwsPiMW/4s4EqUWaq29WYQsZj+xUFAlQHLG1VOorjD+UU30Yj3acr4O3b/5iDfsW+2zDc1UB/T+fvzMv6nLNIMJAVST+7GulAbzcmItrdcWi9UN6VWICYatg6QFi2eJIibfwrorzA2v4NXUrja2/OpbePDeIW0NmU2y+U9kl2n0XvQOy87751iRE0bFzRBOzURumh+ZE7pYDXodf50B72bPl/ytKUPzwMOCzOA4qRoROWHwCh5puT8i1FHN8HGykZCZE7s3Enf7UpJ8hp4N4caODQCeBJhISSosN0YTCNIsT76CjyXQwQOMVrDGLQ==</Modulus><Exponent>AQAB</Exponent><P>81hQqq4N6+ejjtvynaALqwrGX9A7F6xhipYRGUzT4bQ+6n/Z2maADtOw1k2nd1Uz6NmneYGtQkzkqpEgQvJ89Ds0m/ndDqySKpV+qWJzW8QeLmm7rqhcVmjMqaTYYfb2nJj0C7a9ixf8JsKKV5I6Q4E8iZNDJQkD0Ap1mXwEXX8=</P><Q>411gemkRFxg/mu51aHk6F/D/kfgBZHV7pGohzgJ3LFFfDxsLviWeLLWcLna9nV9YZpP7QaNchIHOiRq63I/JPn9E+gieTWpAFTLOVhNRdchdI8sE/OUTE7Q8CAeNHlZWqv6DZpUxPBWNFaqO2zuq2t104CAItwFfp+599mkgilM=</Q><DP>OA2Hx0kAe+6HhkizwgszpNp+h2N3uSRD86BNn/5KcBsMwwdgLyadKM0qVrLceGhv5Jr+MMbmGfeMVJ3JSKKCld9tZuBPQyoNITH+UxYSbHjoWtiQGtM9McpCGnGWRjqU4813qZsWXgvQUT1OkI1mTlZek3IQbV9+OVWvcQNYHhE=</DP><DQ>a1ehfglurSWgmefs/GcHe1gngOXC2ofw2N3WmelmFEFSjNIrCBnAhME1PGaI/OyP0tYYsJOM0W5rcSVyhUFJNL1ndlhtTIVWPevfqJm0QtRWzNhDwZXxHMNh+DSAdosyncZNiTf0p7ZRBqKgkXapIm2diVb2Zlg6rhEV3Ski2Ms=</DQ><InverseQ>XQJzVm1AFLJkbsrGb19MUOauBiDzlssX8VXT3A9gB0zsVclhgWpZMMKia1iAgrTg5nqhy2PIqvBJ9Vu3GGO6IP0lmLXwI83cOhso7AIz9dAknI4xR4LlLKtnbmw6ozwWMzxx+5fsKDbnTB5wiAIepZDXARdm9bmr791mXJXZQWA=</InverseQ><D>YbeygOaOAscVVED2FB6B5oa3Ww2jPV8BNX59VlTFO2udmr07k+mFYrIx/Z9HjkmakVO+kQVFkyuzOsD7GMEFclUSrYfeNsXZEhXwAXuMmbYMFgyPBEZ4+Eqgi/ZOmS+RxrFi1Mt6VD8jWGdHyabeCOdBpircbf9d8Q9ZL7eOx0tKAnn4QCcxxErDsRbAYLWKF8SClSGgEu2sfvBU/zMvJ2Lm6XTepItyfzWp+/eiN6ovg6OjuUtg4p7i8jEWP7M/LmLqAusjBtSve+0HF+d38DyD2kL6+ocIPwpXyuY5DjMazJtTCarmr+ryKkiUdFRtmwRf6XufFZSHrsEnmzEp0w==</D></RSAKeyValue>"
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
rsa.FromXmlString(xmlKey);
byte[] decryptedData = rsa.Decrypt(inputBuf, false);

您可以看到字符串中的每个 xml 标签都对应了密钥的每个组成部分。

一个 public 密钥只包含一个模数和一个指数。添加所有其他组件使密钥成为私有的。您设置的值缺少一些私有组件,这就是为什么 PublicOnly 为真。为了避免混淆,Public 密钥是加密数据的密钥,私钥是解密它的唯一方法,您将在 C# 服务器代码中使用它。

(本例中的密钥是2048,您使用1024即可)