在C#中加密的数据长度为1个字节,无法在Java中解密 [英] Data encrypted in C# is 1 byte too long to be decrypted in Java

查看:209
本文介绍了在C#中加密的数据长度为1个字节,无法在Java中解密的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a server written in Java which sends converts its RSA key to the XML format used by .NET before sending it to the client:

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 = 
            "<RSAKeyValue>" +
                "<Modulus>%s</Modulus>" +
                "<Exponent>%s</Exponent>" +
            "</RSAKeyValue>";

        return String.format(format, modulusStr, exponentStr);
    } catch (Exception e) {
        this.server.logException(e);
        return "";
    }
}

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

The client, written in C#, then loads the key and uses it to encrypt a 256 bit AES key:

    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密钥:

The server is then supposed to decrypt the AES key using its private RSA key:

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字节。为什么加密数据总是比预期长一个字节?

However, the server fails with an error stating "Data must not be longer than 384 bytes." Looking at the data to be decrypted, I noticed that it's 385 bytes. I tried increasing the RSA key length, and now the server tells me the data must be no longer than 512 bytes, while the encrypted data from the client is 513 bytes. Why is the encrypted data always one byte longer than expected?

编辑:

这是XML格式的示例键作为从服务器发送到客户端:

Here's a sample XML-formatted key as is transmitted from the server to the client:

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

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

I have verified that the data sent is the same as the data being received.

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

Knocking off the last byte results in a BadPaddingException. I also tried knocking off the first byte, with the same result.

推荐答案

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

I found the problem. The BigInteger's toByteArray() function included a leading zero for some reason. I just removed the leading zeros from the array and it now works like a charm!

这篇关于在C#中加密的数据长度为1个字节,无法在Java中解密的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆