代码之家  ›  专栏  ›  技术社区  ›  chef

使用RSACryptoServiceProvider解密失败

  •  0
  • chef  · 技术社区  · 11 年前

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

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

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

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

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

    当我这样做时,会抛出一个异常“坏数据”。当我将公钥添加到

    keyInfo.Exponent = pubExpBytes

    然后它通过,但稍后会在方法中引发异常“Key不存在”

    result = rsa.Decrypt(inputBuf, false);
    

    尽管我在“keyInfo.D”中添加了密钥,但属性“PublicOnly”为真。

    我做错了什么?

    1 回复  |  直到 11 年前
        1
  •  1
  •   Animal Style    11 年前

    使用RSACryptoServiceProvider时,私钥由要设置的模数、指数、P、Q、DP、DQ、反向Q和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为true的原因。为了避免混淆,公钥是加密数据的工具,而私钥是解密数据的唯一方法,这将在C#服务器代码中使用。

    (本例中的密钥为2048,只需使用1024即可)

    推荐文章