c# - 在 C# 中加密的数据是 1 个字节太长,无法在 Java 中解密

标签 c# java rsa

我有一个用 Java 编写的服务器,在将其发送到客户端之前将其 RSA key 转换为 .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 = 
            "<RSAKeyValue>" +
                "<Modulus>%s</Modulus>" +
                "<Exponent>%s</Exponent>" +
            "</RSAKeyValue>";

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

用 C# 编写的客户端然后加载 key 并使用它来加密 256 位 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;
    }

然后服务器应该使用其私有(private) RSA key 解密 AES 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 key 长度,现在服务器告诉我数据不能超过 512 字节,而来自客户端的加密数据是 513 字节。为什么加密数据总是比预期长一个字节?

编辑:

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

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

我已验证发送的数据与接收的数据相同。

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

最佳答案

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

关于c# - 在 C# 中加密的数据是 1 个字节太长,无法在 Java 中解密,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11729893/

相关文章:

C# 等待进程启动

c# - 如何将 BitArray 转换为单个 int?

c# - 如何在屏幕上运行计时器时运行方法?

java - 无法使用 java webdriver 关闭身份验证弹出窗口

c - libgcrypt-1.8.2 中的 gcry_mpi_t 类型定义

c# - 将 char 数组从 c# 传递到 c++ dll

java - componentListener 被禁用

java - 将相同的 keystore 用于信任库和服务器库时出现安全问题?

java - 如何使用 Java 中的 RSAPrivateKeySpec 类从字符串创建 RSA PrivateKey?

c++ - 莱曼算法没有意义