0%

java异或实现数据加密

文章字数:306,阅读全文大约需要1分钟

异或(xor)两次之后的数据是相同的,根据这个原理可以加密数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
import java.io.BufferedOutputStream;
import java.io.Closeable;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

/**
* 加密解密工具类
*/
public class XORUtils {
/**
* 加密、解密byte数据
* @param data 数据(密文/明文)
* @param key 密钥
* @return 返回解密/加密后的数据
*/
public static byte[] encrypt(byte[] data, byte[] key) {
if (data == null || data.length == 0 || key == null || key.length == 0) {
return data;
}
byte[] result = new byte[data.length];
// 使用密钥字节数组循环加密或解密
for (int i = 0; i < data.length; i++) {
// 数据与密钥异或, 再与循环变量的低8位异或(增加复杂度)
result[i] = (byte) (data[i] ^ key[i % key.length] ^ (i & 0xFF));
}
return result;
}

/**
* 加密、解密文件
* @param inFile 输入文件(密文/明文)
* @param outFile 结果输出文件
* @param key 密钥
*/
public static void encryptFile(File inFile, File outFile, byte[] key) throws Exception {
InputStream in = null;
OutputStream out = null;
try {
// 文件输入流
in = new FileInputStream(inFile);
// 结果输出流, 异或运算时, 字节是一个一个读取和写入, 这里必须使用缓冲流包装,
// 等缓冲到一定数量的字节(10240字节)后再写入磁盘(否则写磁盘次数太多, 速度会非常慢)
out = new BufferedOutputStream(new FileOutputStream(outFile), 10240);

int b = -1;
long i = 0;

// 每次循环读取文件的一个字节, 使用密钥字节数组循环加密或解密
while ((b = in.read()) != -1) {
// 数据与密钥异或, 再与循环变量的低8位异或(增加复杂度)
b = (b ^ key[(int) (i % key.length)] ^ (int) (i & 0xFF));
// 写入一个加密/解密后的字节
out.write(b);
// 循环变量递增
i++;
}
out.flush();
} finally {
close(in);
close(out);
}
}

private static void close(Closeable c) {
if (c != null) {
try {
c.close();
} catch (IOException e) {
}
}
}
}

测试

1
2
3
4
5
6
7
import java.io.File;
public class Main {
public static void main(String[] args) throws Exception {
XORUtils.encryptFile(new File("demo.jpg"), new File("demo.jpg_cipher"), key.getBytes());
XORUtils.encryptFile(new File("demo.jpg_cipher"), new File("demo.jpg_plain"), key.getBytes());
}
}