JS与Java间AES-128 CBC加密传输韩文乱码问题求助
问题原因与解决方法
核心问题是编码不统一:JavaScript加密时用UTF-8编码处理明文,而Java解密后用EUC-KR编码解析字节数组,韩文的UTF-8编码字节被错误解析为EUC-KR,导致乱码。
修复步骤
1. 统一解码编码为UTF-8
修改Java解密代码中字符串转换的编码,和JavaScript端保持一致:
public String aesDecode(String str) throws Exception { System.out.println("INPUT : "+str); Cipher c = Cipher.getInstance("AES/CBC/PKCS5Padding"); c.init(Cipher.DECRYPT_MODE, this.keySpec, new IvParameterSpec(this.iv.getBytes(StandardCharsets.UTF_8))); byte[] decrypted = c.doFinal(Base64.getDecoder().decode(str)); // 替换为UTF-8编码解析 return new String(decrypted, StandardCharsets.UTF_8); }
2. 验证密钥与IV的一致性
确保JavaScript和Java端的Key、IV生成逻辑完全一致:
- JavaScript中如果Key是字符串,
crypto.createCipheriv会直接用字符串的UTF-8字节作为密钥(需确保长度为16字节,符合AES-128要求)。 - Java端的
keySpec必须基于相同的字符串转UTF-8字节生成,比如:SecretKeySpec keySpec = new SecretKeySpec("your-key-string".getBytes(StandardCharsets.UTF_8), "AES"); - IV同理,两端都要使用UTF-8编码的字节数组。
3. 解决填充问题
你之前遇到的“无法发送超过15个字符”的填充问题,是因为手动编码破坏了AES的PKCS5Padding自动填充逻辑。现在统一编码后,JavaScript的cipher.update和cipher.final会自动处理填充,无需额外调整参数。
原理说明
UTF-8是韩文的标准编码(每个韩文字符占3字节),而EUC-KR是旧的韩国编码(每个韩文字符占2字节)。将UTF-8编码的字节用EUC-KR解析时,字节序列不匹配,就会出现乱码;英文和数字在两种编码中兼容,所以显示正常。
内容的提问来源于stack exchange,提问作者Jae Hyun Yoo
相关产品推荐
相关产品推荐

