java流数据实时加密需用aes/cbc/pkcs5padding或aes/gcm/nopadding,配合cipherinputstream/outputstream包装流,cbc需前置iv并手动管理,gcm自带认证但需java 8u161+;务必调用dofinal()或close()确保末块处理,且cbc应额外加hmac防篡改。

Java 中实现流数据的实时加密,核心是使用 可流水线处理的加密算法(如 AES/CBC/PKCS5Padding 或 AES/GCM/NoPadding),配合 javax.crypto.CipherInputStream / CipherOutputStream 对原始输入输出流进行包装,让加解密过程与数据读写同步发生,无需缓存整段数据。
选择适合流式处理的加密模式
AES 的 ECB 模式不安全且不支持流式填充;推荐使用:
- CBC 模式 + PKCS5Padding(或 PKCS7Padding):需手动管理 IV(初始化向量),每次加密前生成并写入流首部;解密时先读 IV 再初始化 Cipher
- GCM 模式(AES/GCM/NoPadding):自带认证、无需填充,天然适合流式传输,但要求 Java 8u161+,且 GCM 的 tag 需在末尾附加(解密时需预留空间或分两阶段处理)
用 CipherOutputStream 实现实时加密写入
以 AES/CBC 为例,典型流程如下:
- 生成随机 16 字节 IV,并通过底层流(如 FileOutputStream)先写入前 16 字节
- 用 SecretKeySpec + IvParameterSpec 初始化 Cipher(ENCRYPT_MODE)
- 将原始 OutputStream 包装为 CipherOutputStream,后续 write() 即自动加密并写入
- 务必调用 cipherOutputStream.doFinal() 或 close() 触发最终块处理(否则最后一块可能丢失)
注意流边界与完整性校验
纯 CipherInputStream/OutputStream 不提供完整性保护:
- 若需防篡改,GCM 是首选——它在加密同时生成认证标签(Authentication Tag),解密时自动校验
- 若用 CBC,建议额外计算并追加 HMAC(如 HmacSHA256)到密文末尾,解密后先验签再解密
- 避免在加密流中混用不同 Cipher 实例或中途重置,会导致 IV 错位、解密失败
简单示例(AES/CBC + IV 前置)
加密端:
SecretKey key = new SecretKeySpec(rawKey, "AES");
byte[] iv = new byte[16];
SecureRandom.getInstanceStrong().nextBytes(iv);
IvParameterSpec ivSpec = new IvParameterSpec(iv);
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, key, ivSpec);
try (FileOutputStream fos = new FileOutputStream("out.enc");
CipherOutputStream cos = new CipherOutputStream(fos, cipher)) {
fos.write(iv); // 先写 IV
cos.write(plainData); // 自动加密写入
}
解密端对应读取前 16 字节作为 IV,再构造 CipherInputStream。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











