在C#中加密的数据长度为1个字节,无法在Java中解密

我有一个用Java编写的服务器,它将其RSA密钥转换为.NET使用的XML格式,然后再将其发送到客户端:

public String getPublicKeyXML() { try { KeyFactory factory = KeyFactory.getInstance("RSA"); RSAPublicKeySpec publicKey = factory.getKeySpec(this.keyPair.getPublic(), RSAPublicKeySpec.class); byte[] modulus = publicKey.getModulus().toByteArray(); byte[] exponent = publicKey.getPublicExponent().toByteArray(); String modulusStr = Base64.encodeBytes(modulus); String exponentStr = Base64.encodeBytes(exponent); String format = "" + "%s" + "%s" + ""; return String.format(format, modulusStr, exponentStr); } catch (Exception e) { this.server.logException(e); return ""; } } 

用C#编写的客户端然后加载密钥并使用它来加密256位AES密钥:

  public static byte[] encrypt(string xmlKey, byte[] bytes) { RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(); rsa.FromXmlString(xmlKey); byte[] cipherBytes = rsa.Encrypt(bytes, false); rsa.Clear(); return cipherBytes; } 

然后,服务器应使用其私有RSA密钥解密AES密钥:

 public byte[] decrypt(byte[] data) { try { PrivateKey privateKey = this.keyPair.getPrivate(); Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); cipher.init(Cipher.DECRYPT_MODE, privateKey); byte[] cipherData = cipher.doFinal(data); return cipherData; } catch (Exception e) { this.server.logException(e); return new byte[0]; } } 

但是,服务器失败并显示“数据不得超过384字节”的错误。 看着要解密的数据,我注意到它是385个字节。 我尝试增加RSA密钥长度,现在服务器告诉我数据必须不超过512字节,而来自客户端的加密数据是513字节。 为什么加密数据总是比预期长一个字节?

编辑:

这是从服务器传输到客户端的XML格式的示例密钥:

 ANsMd2dCF6RsD5v5qjlHEjHm0VWD99gSYHP+pvyU8OgNL9xM5+o+yMAxWISOwMii9vJk1IzYGf18Fj2sMb5BsInlG2boZHb6KHh7v8ObPa4MuwB/U63i8AVU3N/JTugaPH0TKvo1WNUooXEHT23nOk+vh1QipzgKQYGl68qU35vKmpNAa79l1spXA66LckTWal4art9T08Rxgn9cMWujlF+wh9EQKQoxxgj4gCoXWRDTFYjRo/Mp5xDPwNjloTs/vFCPLvY7oI+lVrHhrPyz1R473ZuEhZm+rSeGBcY9I8vhg0AIixN7KYBLhrIecmqoNZHi6LohjD2F9zhdLaTU0IIU8eeKpbEZ5eB1kYngMONBq3A/IoG0Qa/7EcSAMMspBEObffK9kCNzvnbFg5wLuy8EHNaK3nmnuTppgCwCyNqZyHeAbZaUBjNguLhHtqkHFiPJ063Xesj9UbSsCmlBliGTDXWfeJANnjGP6D3R+uLXVy9SZe+cY92JW3eZA2k//w==AQAB 

我已经validation发送的数据与收到的数据相同。

敲掉最后一个字节会导致BadPaddingException。 我也尝试敲掉第一个字节,结果相同。

我发现了问题。 由于某种原因,BigInteger的toByteArray()函数包含一个前导零。 我刚从arrays中删除了前导零,它现在就像一个魅力!

这不会解决问题(我测试它无济于事),但我想提醒您注意RSACryptoServiceProvider实现IDisposable接口,因此在完成时应妥善处理 。 您的C# encrypt方法可以更好地编写(更简洁!):

  public static byte[] encrypt(string xmlKey, byte[] bytes) { using (var rsa = new RSACryptoServiceProvider()) { rsa.FromXmlString(xmlKey); return rsa.Encrypt(bytes, false); } }