使用RSACryptoServiceProvider解密失败

时间:2015-02-05 17:09:51

标签: c# encryption key rsa biginteger

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

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

使用“模数”和“privateKey”初始化“keyInfo”(RSAParameters)变量

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

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

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

中添加公钥时

keyInfo.Exponent = pubExpBytes

然后它通过但是方法

中的“Key not exists”后面会抛出异常
result = rsa.Decrypt(inputBuf, false);

,即使我在“keyInfo.D”中添加了密钥,属性“PublicOnly”也是如此。

我做错了什么?

1 个答案:

答案 0 :(得分:1)

使用RSACryptoServiceProvider时,私钥由要设置的模数,指数,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标记都代表密钥的每个组件。

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

(此示例中的密钥为2048,仅使用1024)