You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

加密消息中出现带问号的菱形字符是否正常?

解答

嘿,刚接触加密遇到这个问题太正常了,我给你掰扯清楚:

首先,你看到的带问号的菱形字符(�)是加密后的正常产物,但你直接把加密字节转成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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 06:47:11