1. 简单介绍

3DES(或称为Triple DES)是三重数据加密算法(TDEA,Triple Data Encryption Algorithm)块密码的通称。它相当于是对每个数据块应用三次DES加密算法。由于计算机运算能力的增强,原版DES密码的密钥长度变得容易被暴力破解;3DES即是设计用来提供一种相对简单的方法,即通过增加DES的密钥长度来避免类似的攻击,而不是设计一种全新的块密码算法。

2. 对称加密

2.1 介绍

对称密码算法是当今应用范围最广,使用频率最高的加密算法。它不仅应用于软件行业,在硬件行业同样流行。各种基础设施凡是涉及到安全需求,都会优先考虑对称加密算法。对称密码算法的加密密钥和解密密钥相同,对于大多数对称密码算法,加解密过程互逆。

  • 特点:算法公开、计算量小、加密速度快、加密效率高。

  • 弱点:双方都使用同样密钥,安全性得不到保证。

对称密码有流密码和分组密码两种,但是现在普遍使用的是分组密码:

2.2 分组密码工作模式

  • ECB:电子密码本(最常用的,每次加密均产生独立的密文分组,并且对其他的密文分组不会产生影响,也就是相同的明文加密后产生相同的密文)
  • CBC:密文链接(常用的,明文加密前需要先和前面的密文进行异或运算,也就是相同的明文加密后产生不同的密文)
  • CFB:密文反馈
  • OFB:输出反馈
  • CTR:计数器

2.3 常用对称密码:

  • DES(Data Encryption Standard,数据加密标准)
  • 3DES(Triple DES、DESede,进行了三重DES加密的算法)
  • AES(Advanced Encryption Standard,高级数据加密标准,AES算法可以有效抵制针对DES的攻击算法

3. DES / 3DES / AES 三种算法实现

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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

import com.newland.csf.common.business.IBusinessComponent;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.nio.charset.StandardCharsets;

/**
*
*
*
*/
public class TripleDes {

//指定要使用的算法 DES / 3DES / AES 分别对应的 值为: DES / DESede / AES
public static final String ALGORITHM_3DES = "DESede";

/**
* 解密算法
* @param hexString 密文手机号
* @param skString 密钥
* @return
* @throws Exception
*/
public static String tripleDesDecrypt(String skString, String hexString) throws Exception {
SecretKey secretKey = new SecretKeySpec(fromHexString(skString), ALGORITHM_3DES);
byte[] input = fromHexString(hexString);
byte[] output = tripleDesDecryptBytes(secretKey, input);
return new String(output, StandardCharsets.UTF_8);
}

/**
* 加密算法
* @param hexString 明文手机号
* @param skString 密钥
* @return
* @throws Exception
*/
public static String tripleDesEncrypt(String skString, String hexString) throws Exception {
SecretKey secretKey = new SecretKeySpec(fromHexString(skString), ALGORITHM_3DES);
byte[] output = tripleDesEncryptBytes(secretKey, hexString.getBytes(StandardCharsets.UTF_8));
return bytes2Hex(output, false);
}

public static String bytes2Hex(byte[] bytes, boolean upperCase) {
if (bytes == null || bytes.length <= 0) {
return "";
}
StringBuilder sb = new StringBuilder();
for (byte b : bytes) {
sb.append(String.format("%02x", b));
}
return upperCase ? sb.toString().toUpperCase() : sb.toString();
}

public static byte[] fromHexString(final String hexString) {
if ((hexString.length() % 2) != 0) {
throw new IllegalArgumentException(
"hexString.length not is an even number");
}

final byte[] result = new byte[hexString.length() / 2];
final char[] enc = hexString.toCharArray();
StringBuilder sb = new StringBuilder(2);
for (int i = 0; i < enc.length; i += 2) {
sb.delete(0, sb.length());
sb.append(enc[i]).append(enc[i + 1]);
result[i / 2] = (byte) Integer.parseInt(sb.toString(), 16);
}
return result;
}

public static byte[] tripleDesEncryptBytes(SecretKey secretKey, byte[] src) throws Exception {
Cipher c1 = Cipher.getInstance(ALGORITHM_3DES);
c1.init(Cipher.ENCRYPT_MODE, secretKey);
return c1.doFinal(src);
}

public static byte[] tripleDesDecryptBytes(SecretKey secretKey, byte[] src) throws Exception {
Cipher c1 = Cipher.getInstance(ALGORITHM_3DES);
c1.init(Cipher.DECRYPT_MODE, secretKey);
return c1.doFinal(src);
}

/**
* 加密文件
* @param skString
* @param srcFilePath
* @param desFilePath
* @throws Exception
*/
public static void tripleDesEncryptFile(String skString,String srcFilePath,String desFilePath) throws Exception {
Cipher cipher = Cipher.getInstance(ALGORITHM_3DES);
SecretKey secretKey = new SecretKeySpec(fromHexString(skString), ALGORITHM_3DES);
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
writeFile(cipher,srcFilePath,desFilePath);
}

/**
* 解密文件
* @param skString
* @param srcFilePath
* @param desFilePath
* @throws Exception
*/
public static void tripleDesDecryptFile(String skString,String srcFilePath,String desFilePath) throws Exception {
Cipher cipher = Cipher.getInstance(ALGORITHM_3DES);
SecretKey secretKey = new SecretKeySpec(fromHexString(skString), ALGORITHM_3DES);
cipher.init(Cipher.DECRYPT_MODE, secretKey);
writeFile(cipher,srcFilePath,desFilePath);
}

private static void writeFile(Cipher cipher,String srcFilePath,String desFilePath) throws Exception{
byte[] buff = new byte[512];
byte[] temp = null;
int len = 0;
try (FileInputStream fis = new FileInputStream(new File(srcFilePath));
FileOutputStream fos = new FileOutputStream(new File(desFilePath))) {
while ((len = fis.read(buff)) > 0) {
temp = cipher.update(buff, 0, len);
fos.write(temp);
}
temp = cipher.doFinal();
if (temp != null) {
fos.write(temp);
}
}
}
}


----------

微信公众号


欢迎关注公众号“云栖简码”