fileinputstream + xor 加密最轻量,因仅用java标准库、支持任意二进制文件、加解密逻辑相同且密钥一致即可逆。

为什么用 FileInputStream + XOR 做文件加密最轻量?
因为不需要引入任何第三方库,Java 标准库就能完成,且对任意二进制文件(图片、PDF、ZIP)都有效。核心逻辑就是逐字节读取 + 异或运算,加解密用同一段代码,只是密钥一致即可逆。
常见错误现象:java.io.IOException: Stream closed —— 多半是 FileInputStream 或 FileOutputStream 被提前 close(),或者 try-with-resources 里写了两次资源声明;还有人误把字符串密钥直接当字节用,导致加密后文件乱码无法还原。
- 密钥必须是
byte类型,别用"abc".getBytes()后不指定编码(默认平台编码不稳定),统一用"abc".getBytes(StandardCharsets.UTF_8) - 异或操作只支持
byte和int,别对long或String直接异或 - 每次读取建议用
byte[] buffer = new byte[8192],别单字节循环,否则 I/O 性能差十倍以上
FileOutputStream 写入时乱码或文件损坏怎么办?
本质是没按原始字节原样写出:比如把加密后的 byte[] 转成 String 再写入,或用了 PrintWriter 这类字符流。二进制文件加密/解密必须全程使用字节流。
使用场景:你拿到一个加密后的 .enc 文件,想还原成原始 .jpg,但解密后打不开——大概率是写入时被当成文本处理了。
- 绝对不用
FileWriter、PrintWriter、BufferedWriter - 写入必须用
FileOutputStream.write(byte[]),且传入的是原始加密/解密后的字节数组 - 如果要加文件头(如 magic number),得手动在
byte[]开头插入,不能靠“重命名”或“追加文本”
异或加密为什么能“加解密同逻辑”,但又不安全?
因为 a ^ b ^ b == a,所以用同一密钥对同一数据异或两次就回到原值。这是数学恒等式,和语言无关,也是它适合教学演示的原因。
但它不是生产级加密:密钥长度固定、无扩散、无混淆、抗不了频率分析。如果原始文件有大量连续 0x00(比如空白 PNG),加密后会暴露密钥周期性模式。
- 单字节密钥(如
new byte[]{0x1F})等于凯撒密码,一查统计就破 - 推荐用与文件等长的密钥(如 SHA-256 摘要扩展),但实际中更常用 AES
- 如果你只是想临时隐藏配置文件或学生作业,
XOR足够;想防同事翻看,也还行;想防工具扫描,就不够了
读写大文件时内存爆掉或卡死怎么调?
典型表现:加密一个 2GB 的视频,堆内存溢出(OutOfMemoryError: Java heap space),或者卡住十几秒没响应。问题不在算法,而在缓冲区和流管理。
性能影响关键点:缓冲区太小 → 系统调用太多;缓冲区太大 → 一次性分配超限;没及时 flush() → 数据滞留在缓冲区未落盘。
- 缓冲区设为
8192(8KB)到65536(64KB)之间较稳,别盲目上1024 * 1024 - 用 try-with-resources 包住
FileInputStream和FileOutputStream,别手动close()两次 -
FileOutputStream构造时加true参数是追加模式,加密必须用false(覆盖写)
真正容易被忽略的是密钥复用方式:同一个密钥反复用于多个文件,一旦其中任一明文已知,其余全可推导。哪怕只是测试,也别用固定 new byte[]{1,2,3} 硬编码在源码里。










