【问题标题】:Netty StreamCorruptedException After Keyexchange密钥交换后的 Netty StreamCorruptedException
【发布时间】:2021-04-12 13:55:04
【问题描述】:

我正在尝试使用 AES 建立加密的 Netty 连接。 RSA 正在帮助我传输 AES 密钥和 iv。

服务器和客户端在交换后拥有相同的密钥和iv。我正在创建密码 实际上用它来解密和加密东西。 当我在 Eclipse 中使用 Cp1252 编码在我的电脑上运行服务器时,它工作正常。 一旦我将编码更改为 UTF-8(编码我的客户端是写入的)或在我的 Linux 系统上运行服务器,它就不再工作了。

我看到我可以使用 cipher.getIV(); 从密码中获取 iv,不幸的是它们不一样 所以这可能是问题所在。

Exception (client)

Server output

如您所见,AES 密钥和 IV 相同。

这就是我生成密码的方式

public static Cipher generateCipher(byte[] secret, int mode, byte[] iv) {
        KeySpec spec = new PBEKeySpec(new String(secret).toCharArray(), iv, 65536, 128);
        try {
            byte[] key = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1").generateSecret(spec).getEncoded();
            SecretKeySpec secretKey = new SecretKeySpec(key, "AES");

            Cipher cipher = Cipher.getInstance("AES/CFB8/NoPadding");
            IvParameterSpec parameterSpec = new IvParameterSpec(secretKey.getEncoded());

            cipher.init(mode, secretKey, parameterSpec);
            return cipher;

        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }

这就是我打印字符串的方式

byte[] aesKey = CryptionUtils.decryptRSA(packet.getKey(), rsaKeys.getPrivate());
byte[] iv = CryptionUtils.decryptRSA(packet.getIv(), rsaKeys.getPrivate());

if (iv.length != 12 || aesKey.length != 16) {
        server.sendPacket(ip, new KickPacket(EnumKickPacket.INVALID_AES_INFO.ordinal()));
        server.disconnectClient(ip, EnumKickPacket.INVALID_AES_INFO.name());
}

Cipher decryptCipher = CryptionUtils.generateCipher(aesKey, Cipher.DECRYPT_MODE, iv);
Cipher encryptCipher = CryptionUtils.generateCipher(aesKey, Cipher.ENCRYPT_MODE, iv);

System.out.println("IV: " + Base64.getEncoder().encodeToString(iv));
System.out.println("AESKey: " + Base64.getEncoder().encodeToString(aesKey));
System.out.println("DecryptCipher: " + Base64.getEncoder().encodeToString(decryptCipher.getIV()));
System.out.println("EncryptCipher: " + Base64.getEncoder().encodeToString(encryptCipher.getIV()));

【问题讨论】:

  • 请发布包含示例数据的MCVE,以便进行复制。屏幕截图中的测试数据没有帮助。您正在实例化一个字符串而不指定字符集 (new String(secret))。这可能会导致使用平台的默认字符集,这可能会因跨平台而异并导致问题。同样奇怪的是 KDF 中的 IV(而不是盐)并将密钥用作 IV(而不是随机或 KDF 生成的 IV)。顺便说一句,IV和salt一般都不是秘密,不需要加密。
  • 感谢帮了大忙

标签: java exception networking encryption netty


【解决方案1】:

new String(secret, Charset.forName("UTF-8") 修复了问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-12-22
    • 1970-01-01
    • 2018-02-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-02
    相关资源
    最近更新 更多