用FileOutputStream配合CipherOutputStream实现文件加密写入,核心是先生成AES密钥和随机IV,再用Cipher初始化加密模式,最后通过CipherOutputStream自动加密写入数据并落盘。

用 FileOutputStream 配合 CipherOutputStream 实现文件加密写入,核心是把加密逻辑“套”在输出流链路里:先构建加解密器(Cipher),再用它包装一个文件输出流,后续写入的数据会自动加密并落盘。
准备密钥和初始化向量(IV)
对称加密(如 AES)需要密钥和 IV。密钥应安全生成并妥善保管;IV 每次加密必须唯一(但不必保密),通常随机生成并和密文一起保存。
- 使用
KeyGenerator生成 AES 密钥(如 128/256 位) - 用
SecureRandom生成 16 字节 IV(AES-CBC 或 AES-GCM 所需) - 建议将 IV 写在密文前(如前 16 字节),解密时先读出再初始化 Cipher
构建 Cipher 并初始化为加密模式
选择合适算法/模式/填充(例如 AES/CBC/PKCS5Padding 或更安全的 AES/GCM/NoPadding),用密钥和 IV 初始化 Cipher 为 ENCRYPT_MODE。
- 注意 GCM 模式需设置
setTagLength()(如 128),且 IV 长度通常为 12 字节 - 避免硬编码算法字符串,优先使用标准名称(如
"AES/GCM/NoPadding") - 捕获
InvalidKeyException、InvalidAlgorithmParameterException等异常
用 CipherOutputStream 包装 FileOutputStream
创建 FileOutputStream 指向目标文件,再把它传给 CipherOutputStream 构造函数 —— 这样所有写入操作都会经 Cipher 加密后再写入磁盘。
立即学习“Java免费学习笔记(深入)”;
- 推荐使用 try-with-resources 确保流正确关闭(
CipherOutputStream关闭时会自动 flush 并调用底层流 close) - 不要在加密流外再手动调用
flush()或close()底层FileOutputStream - 写入原始字节(
write(byte[])或write(int)),文本内容建议先转 UTF-8 字节数组再写
完整示例(AES/CBC/PKCS5Padding)
以下代码生成密钥与 IV,加密字符串后写入文件:
<font size="2"><pre class="brush:php;toolbar:false;">SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES");
IvParameterSpec ivSpec = new IvParameterSpec(ivBytes);
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec);
try (FileOutputStream fos = new FileOutputStream("encrypted.dat");
CipherOutputStream cos = new CipherOutputStream(fos, cipher)) {
cos.write("Hello, encrypted world!".getBytes(StandardCharsets.UTF_8));
} // 自动加密、写入、关闭
注意:实际项目中密钥管理、IV 存储、异常处理、GCM 认证标签处理等需更严谨 —— 但流程主干就是这四步。


















