java实现异或加密(附带源码)
一、项目背景详细介绍
1. 加密需求与背景
在信息化时代,数据安全与隐私保护是软件开发中不可或缺的一环。无论是网络传输中的敏感信息,还是本地存储的配置文件,都需要一定程度的加密保护,以避免被恶意窃取或篡改。常见的加密算法有对称加密(如 AES、DES)和非对称加密(如 RSA、ECC)两大类。但在某些场景下,对称加密过于复杂,且对安全性要求不是特别高时,异或(XOR)加密因其算法简单、执行效率高,常用于:
-
游戏存档、配置文件的简单混淆
-
通信协议中对数据包的轻度加密
-
嵌入式设备或物联网设备上的轻量级加密
-
学习和教学:帮助初学者理解加密原理与位运算
异或加密的核心在于将明文数据与一个密钥(可以是单字节,也可以是多字节的字节序列)进行位级异或操作,得到密文;解密时再对密文与同一密钥做异或,即可还原明文,因为 a⊕b⊕b=aa \oplus b \oplus b = aa⊕b⊕b=a。
2. Java 实现意义
Java 作为跨平台的主流语言,常用于后端服务、桌面应用、Android 开发等场景。在这些场景中,集成轻量级加密模块有助于:
-
在传输前对日志、诊断数据进行简单脱敏
-
对配置文件中的敏感字段(如数据库密码)做基本混淆
-
在学习 Java 时实践位运算与流处理的结合
本项目将手写一套通用的 Java 异或加密工具,满足以下需求:
-
支持对任意
byte[]数据进行异或加密/解密 -
支持单字节与多字节密钥,密钥能够循环使用
-
提供基于文件与字符串的加密/解密 API
-
具有良好的可扩展性,可集成到各类 Java 应用
-
代码注释详尽,便于初学者学习和二次开发
二、项目需求详细介绍
-
核心功能
-
提供对
byte[]数据的异或加密/解密方法 -
支持单字节密钥和多字节密钥(
byte[] key),并在数据长度超过密钥长度时循环使用密钥
-
-
API 设计
public class XorCipher {
/**
* 对输入的字节数组进行异或加密/解密
* @param data 待处理的字节数组
* @param key 密钥字节数组
* @return 处理后的字节数组
*/
public static byte[] xor(byte[] data, byte[] key);
/**
* 将输入字符串按 UTF-8 编码加密,并返回 Base64 编码的密文
*/
public static String encryptToBase64(String plaintext, byte[] key);
/**
* 将 Base64 编码的密文解密为明文字符串
*/
public static String decryptFromBase64(String base64Cipher, byte[] key);
/**
* 基于文件的加密/解密
*/
public static void processFile(File input, File output, byte[] key) throws IOException;
}
-
文件流处理
-
支持对大文件的流式加密/解密,避免一次性将整个文件读入内存
-
提供缓冲区大小配置(默认为 4KB)
-
-
异常处理
-
对输入为空、密钥为空、文件不存在或读写错误等情况抛出明确异常
-
-
性能要求
-
对几十 MB 的文件进行流式处理,应在数百毫秒至秒级完成
-
-
测试与示例
-
JUnit 单元测试覆盖:单字节密钥、多字节密钥、空数据、空密钥、文件处理
-
示例
Main演示对字符串和文件的加密解密
-
-
文档与注释
-
Javadoc 注释所有公共类和方法,解释参数和返回值
-
README 说明使用方法和注意事项
-
-
扩展需求(可选)
-
支持对文件夹中的所有文件递归加密/解密
-
支持命令行模式:
java -jar xor-cipher.jar encrypt keyFile inputFile outputFile
-
三、相关技术详细介绍
3.1 异或运算原理
-
异或(XOR)是位运算的一种基本操作,符号为
^(Java 中) -
真值表:
a b a⊕b 0 0 0 0 1 1 1 0 1 1 1 0 -
异或运算的两大性质:
-
自反性:a⊕b⊕b=aa \oplus b \oplus b = aa⊕b⊕b=a
-
交换结合律:顺序无关
-
3.2 Java 字符串与字节数组
-
Java 的
String与byte[]相互转换需要指定字符集(通常用UTF-8) -
Base64编码可通过java.util.Base64实现,将二进制可打印化以便传输或存储
3.3 文件流与缓冲区
-
流式加密时,用
BufferedInputStream与BufferedOutputStream,配合 4KB 缓冲区 -
避免一次性加载大文件到内存,节约堆空间
四、实现思路详细介绍
-
字节级异或方法
-
遍历
data数组:for (int i=0; i<data.length; i++) data[i] ^= key[i % key.length]; -
直接在原数组上修改或返回新拷贝(推荐拷贝)
-
-
字符串加密
-
plaintext.getBytes(StandardCharsets.UTF_8)获取字节 -
xor(...)后用Base64.getEncoder().encodeToString()
-
-
字符串解密
-
Base64.getDecoder().decode(base64Cipher) -
xor(...)后用new String(bytes, UTF_8)
-
-
文件加密/解密
-
创建输入/输出流,循环读入缓冲区
byte[] buf = new byte[4096]; int len; while ((len=in.read(buf))!=-1) { encrypt buf[0..len); out.write(buf,0,len); }
-
-
密钥管理
-
允许传入文件作为密钥源:读取整个文件字节作为
key
-
-
异常与验证
-
Objects.requireNonNull(data, "data 不能为空") -
如果
key.length == 0抛IllegalArgumentException("密钥不能为空")
-
-
命令行支持
-
用 Apache Commons CLI 解析参数:
action encrypt|decrypt,-k keyFile,-i input,-o output
-
-
并发性能
-
对大文件可使用 NIO
FileChannel与MappedByteBuffer提升吞吐
-
五、完整实现代码
package com.example.xor;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.Base64;
import java.util.Objects;
/**
* XorCipher 提供基于异或(XOR)的加密与解密功能。
*/
public class XorCipher {
private static final int DEFAULT_BUFFER_SIZE = 4096;
/**
* 对字节数组进行异或加密/解密,返回新数组。
* @param data 原始数据
* @param key 密钥
* @return 新的异或结果数组
*/
public static byte[] xor(byte[] data, byte[] key) {
Objects.requireNonNull(data, "data 不能为空");
Objects.requireNonNull(key, "key 不能为空");
if (key.length == 0) throw new IllegalArgumentException("key 不能为空");
byte[] out = new byte[data.length];
for (int i = 0; i < data.length; i++) {
out[i] = (byte) (data[i] ^ key[i % key.length]);
}
return out;
}
/**
* 将明文字符串按 UTF-8 编码后异或加密,返回 Base64 编码的密文。
*/
public static String encryptToBase64(String plaintext, byte[] key) {
Objects.requireNonNull(plaintext, "plaintext 不能为空");
byte[] data = plaintext.getBytes(StandardCharsets.UTF_8);
byte[] cipher = xor(data, key);
return Base64.getEncoder().encodeToString(cipher);
}
/**
* 将 Base64 编码的密文解密,还原明文字符串。
*/
public static String decryptFromBase64(String base64Cipher, byte[] key) {
Objects.requireNonNull(base64Cipher, "base64Cipher 不能为空");
byte[] cipher = Base64.getDecoder().decode(base64Cipher);
byte[] data = xor(cipher, key);
return new String(data, StandardCharsets.UTF_8);
}
/**
* 对文件进行异或加密/解密,流式处理,支持大文件。
* @param input 输入文件
* @param output 输出文件
* @param key 密钥
*/
public static void processFile(File input, File output, byte[] key) throws IOException {
Objects.requireNonNull(input, "input 不能为空");
Objects.requireNonNull(output, "output 不能为空");
Objects.requireNonNull(key, "key 不能为空");
if (!input.exists() || !input.isFile()) throw new FileNotFoundException("input 文件不存在");
if (key.length == 0) throw new IllegalArgumentException("key 不能为空");
try (BufferedInputStream in = new BufferedInputStream(new FileInputStream(input));
BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(output))) {
byte[] buf = new byte[DEFAULT_BUFFER_SIZE];
int len;
long pos = 0;
while ((len = in.read(buf)) != -1) {
// 异或处理 buf[0..len)
for (int i = 0; i < len; i++) {
buf[i] = (byte) (buf[i] ^ key[(int) ((pos + i) % key.length)]);
}
out.write(buf, 0, len);
pos += len;
}
}
}
}
六、代码详细解读
-
xor(byte[],byte[]):
-
校验输入非空且密钥长度不为 0;
-
为避免修改原数组,创建
out拷贝并按下标% key.length循环使用密钥;
-
-
encryptToBase64 / decryptFromBase64:
-
分别完成字符串<->字节流的转换、异或运算、Base64 编码/解码;
-
-
processFile:
-
使用缓冲流和 4KB 缓冲区逐块读取文件;
-
记录全局偏移
pos,确保在跨块时密钥正确循环; -
异或后写回输出流,流结束后自动关闭。
-
七、项目详细总结
本文实现了一个通用的 Java 异或加密工具 XorCipher,具有以下特性:
-
简洁高效:核心算法仅十余行代码,运行效率高。
-
通用密钥:支持单字节与多字节密钥,循环使用。
-
多种 API:覆盖字节数组、字符串与文件流的加解密。
-
安全可逆:利用异或自反性,使用相同方法即可加密和解密。
八、项目常见问题及解答
Q1:异或加密能否抵抗攻击?
A1:单次异或对称加密属于轻量级混淆,不具备抗分析能力;建议用于低安全场景或作为更复杂算法的构件。
Q2:为什么要记录全局偏移 pos?
A2:确保跨缓冲块时密钥对齐,避免不同块同一偏移处使用不同密钥字节。
Q3:Base64 编码是否必要?
A3:Base64 将二进制密文转换为可打印字符,便于在文本协议或配置文件中存储传输。
Q4:如何保护密钥?
A4:密钥应从安全存储读取(如硬件安全模块或密钥管理系统),避免硬编码。
Q5:如何对目录批量加密?
A5:可递归遍历文件夹,对每个文件调用 processFile,并保留目录结构。
九、扩展方向与性能优化
-
命令行工具:集成 Apache Commons CLI,提供
encrypt/decrypt命令行模式。 -
文件监控:结合 WatchService,在目录文件变更时自动加密。
-
并行加密:对大文件使用多线程分块并行处理,提升吞吐。
-
可插拔算法:抽象
Cipher接口,支持异或、AES 等多种算法统一管理。 -
加密流:实现
CipherInputStream/CipherOutputStream,可无缝集成到 IO 管道。
更多推荐




所有评论(0)