java中aes加密xml节点须先序列化element为utf-8字符串再加密,用gcm模式(iv固定12字节)、base64编码后存入cdata或新元素;解密需原样读取iv/tag、校验base64长度,避免空格干扰。

Java里用AES加密XML节点,别碰Document对象本身
直接对Document或Element调用加密逻辑会失败——XML对象不是字节数组,AES只认byte[]。必须先把目标节点序列化成字符串,再加密,最后替换成CDATA或新元素。
- 正确做法:用
Transformer把Element转为String,再走标准AES加密流程 - 错误现象:
ClassCastException或空指针,因为传了Node给Cipher.doFinal() - 注意编码:序列化时显式指定
UTF-8,否则解密后中文变乱码
选Cipher.getInstance("AES/GCM/NoPadding"),别用CBC
GCM模式自带完整性校验,解密时能立刻发现密文被篡改或密钥错误;而CBC需要额外加HMAC,否则存在填充预言攻击风险。XML节点加密后要嵌回文档,完整性比单纯保密更重要。
- 必须传
IvParameterSpec和SecretKeySpec,缺一不可 -
GCM的IV长度固定12字节(96位),别用8或16字节,否则抛InvalidAlgorithmParameterException - 加密后要把IV、密文、认证标签(
getTag())一起保存,解密时全都要用上
加密后怎么塞回XML?用CDATA最省事但有边界
把加密后的Base64字符串包进,避免XML特殊字符(如、<code>&)引发解析错误。但要注意:某些老系统或非标准解析器可能不支持CDATA嵌套,或者对长度有限制。
- 示例写法:
element.setTextContent(""); - 更稳妥的替代方案:新建一个子元素(如
<encrypted></encrypted>),把Base64放进去,再加iv和tag属性 - 别用
setTextContent()直接塞二进制字节数组——会触发XML编码转换,密文就废了
解密时Transformer解析CDATA内容容易丢数据
用element.getTextContent()读CDATA段,看似简单,但JDK默认DocumentBuilder可能把换行、空格归一化,导致Base64字符串末尾的=被吃掉,解密直接报IllegalBlockSizeException。
立即学习“Java免费学习笔记(深入)”;
- 安全读法:用
NodeList遍历子节点,找到Node.CDATA_SECTION_NODE类型,再调用getNodeValue() - 拿到字符串后,先
trim()再Base64.getDecoder().decode(),避免前后空格干扰 - 解密前务必校验Base64长度是否为4的倍数,不是就说明文本已被破坏









