密钥交换后的 Netty StreamCorruptedException
Netty StreamCorruptedException After Keyexchange
我正在尝试使用 AES 建立加密的 Netty 连接。
RSA 正在帮助我传输 AES 密钥和 iv.
服务端和客户端交换后的key和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()));
new String(secret, Charset.forName("UTF-8")
修复了问题。
我正在尝试使用 AES 建立加密的 Netty 连接。 RSA 正在帮助我传输 AES 密钥和 iv.
服务端和客户端交换后的key和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()));
new String(secret, Charset.forName("UTF-8")
修复了问题。