加密消息中出现带问号的菱形字符是否正常?
解答
嘿,刚接触加密遇到这个问题太正常了,我给你掰扯清楚:
首先,你看到的带问号的菱形字符(�)是加密后的正常产物,但你直接把加密字节转成UTF-8字符串的操作有点不合理,具体原因和解决办法如下:
1. 为什么会出现这种奇怪字符?
AES加密输出的是纯二进制字节流,这些字节的取值覆盖了byte类型的全范围(-128到127),但UTF-8编码只认特定范围内的合法字节序列。当你用new String(encryptedTemp, StandardCharsets.UTF_8)转换时,解码器碰到那些不符合UTF-8规则的字节,就会用替换字符�来代替——这完全是编码转换的正常行为,而且因为你解密用的是原始的加密字节数组,所以解密功能不受影响。
2. 代码核心逻辑没问题,但有个小坑
你的加密和解密核心代码是正确的(不然解密也没法正常工作),但把加密后的二进制字节直接转成UTF-8字符串来展示/存储的做法不恰当:
- 如果只是临时打印调试,倒没大碍;但如果要把加密结果存到数据库或者通过网络传输,这么做会导致数据丢失——因为�字符无法还原回原来的加密字节,到时候再解密就会失败。
3. 正确的处理方式
如果需要把加密后的二进制数据转成可安全存储/传输的字符串,应该用Base64编码,它能把任意二进制字节转换成ASCII范围内的可读字符串,不会丢失任何信息。给你改一段示例代码:
byte[] originalMessage = MESSAGE.getBytes(); System.out.println("Byte[]: " + Arrays.toString(originalMessage)); System.out.println("Original: " + MESSAGE); EnDat newEncryption = new EnDat(KEY); byte[] encryptedTemp = newEncryption.getEncryptMessage(originalMessage); System.out.println("Byte[]: " + Arrays.toString(encryptedTemp)); // 用Base64把加密字节转成可打印的安全字符串 String encryptedBase64 = Base64.getEncoder().encodeToString(encryptedTemp); System.out.println("Encrypted (Base64): " + encryptedBase64); // 解密时先把Base64字符串转回字节数组 byte[] decryptedTemp = newEncryption.getDecryptMessage(Base64.getDecoder().decode(encryptedBase64)); System.out.println("Byte[]: " + Arrays.toString(decryptedTemp)); System.out.println("Decrypted: " + new String(decryptedTemp, StandardCharsets.UTF_8));
另外给你提个小建议:你现在用的是AES/ECB模式,这个模式其实不太安全——相同的明文块会生成相同的密文块,容易被攻击者破解。建议换成AES/CBC或者AES/GCM模式,记得搭配随机生成的初始化向量(IV),这样加密的安全性会提升很多。
内容的提问来源于stack exchange,提问作者wyvern
相关产品推荐
相关产品推荐

