至于 3DES 为什么会出现呢?其实,这个不难想到。由于 DES 是一种非常简便的加密算法,但是密钥长度比较短,计算量比较小,相对来说,比较容易被破解。因此,在 DES 的基础上,使用三重数据加密算法,对数据进行加密,这样来说,破解的概率就小了很多。
1、3DES的概念
1.1 3DES
将密钥长度增至112位或168位,通过增加迭代次数提高安全性。
3DES,也就是“Triple DES”,中文名“三重数据加密算法”,它相当于是对每个数据块应用三次 DES 加密算法。由于计算机运算能力的增强,原版 DES 密码的密钥长度变得容易被暴力破解;3DES 即是设计用来提供一种相对简单的方法,即通过增加 DES 的密钥长度来避免类似的攻击,而不是设计一种全新的块密码算法
1.2 缺点
处理速度较慢、密钥计算时间较长、加密效率不高。
1.3 3DES的实现原理
使用 3 条 56 位的密钥对数据进行三次加密。3DES(即 Triple DES)是 DES 向 AES 过渡的加密算法(1999年,NIST 将 3-DES 指定为过渡的加密标准)。
其具体实现如下:设 Ek() 和 Dk() 代表 DES 算法的加密和解密过程,K 代表 DES 算法使用的密钥,P 代表明文,C 代表密文,这样:
3DES 加密过程为: C = Ek3 ( Dk2 ( Ek1 ( P ) ) )
3DES 解密过程为: P = Dk1 ( EK2 ( Dk3 ( C ) ) )
1.4 JDK实现
2、3DES的编码步骤
2.1 生成密钥
2.1 加/解密
3、3DES算法的实现
TripleDESUtil.java
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;public class TripleDESUtil {/*** 生成密钥* * @return*/public static byte[] initKey() {try {// 秘钥生成器KeyGenerator keyGen = KeyGenerator.getInstance("DESede");// 初始化秘钥生成器keyGen.init(168); // 112 168// 生成密钥SecretKey secretKey = keyGen.generateKey();return secretKey.getEncoded();} catch (Exception e) {throw new RuntimeException(e);}}/*** 使用DES算法,对数据进行加密* * @param data* 要加密的数据* @param key* 加密数据的秘钥* @return*/public static byte[] encrypt(byte[] data, byte[] key) {try {// 恢复密钥SecretKey secretKey = new SecretKeySpec(key, "DESede");// cipher完成加密或者解密Cipher cipher = Cipher.getInstance("DESede/ECB/PKCS5Padding");// 根基密钥,对Cipher进行初始化ENCRYPT_MODE(加密),DECRYPT_MODE(解密)cipher.init(Cipher.ENCRYPT_MODE, secretKey);// 解密/加密byte[] cipherBytes = cipher.doFinal(data);return cipherBytes;} catch (Exception e) {throw new RuntimeException(e);}}/*** 使用DES数据解密* * @param data* 要解密的数据* @param key* 解密数据用到的秘钥* @return*/public static byte[] decrypt(byte[] data, byte[] key) {try {// 恢复密钥SecretKey secretKey = new SecretKeySpec(key, "DESede");// cipher完成加密或者解密Cipher cipher = Cipher.getInstance("DESede/ECB/PKCS5Padding");// 根基密钥,对Cipher进行初始化ENCRYPT_MODE(加密),DECRYPT_MODE(解密)cipher.init(Cipher.DECRYPT_MODE, secretKey);// 解密/加密byte[] plainBytes = cipher.doFinal(data);return plainBytes;} catch (Exception e) {throw new RuntimeException(e);}}
}
字节数组换位
public class BytesToHex {public static String fromBytesToHex(byte[] resultBytes) {StringBuilder builder = new StringBuilder();for (int i = 0; i < resultBytes.length; i++) {if (Integer.toHexString(0xFF & resultBytes[i]).length() == 1) {builder.append("0").append(Integer.toHexString(0xFF & resultBytes[i]));} else {builder.append(Integer.toHexString(0xFF & resultBytes[i]));}}return builder.toString();}}
测试代码
public class Test {// 待加密的明文public static final String DATA = "test";public static void main(String[] args) {long start = System.currentTimeMillis();/* Test 3DES */byte[] tridesKey = TripleDESUtil.initKey();System.out.println("3DES KEY : " + BytesToHex.fromBytesToHex(tridesKey));byte[] tridesResult = TripleDESUtil.encrypt(DATA.getBytes(), tridesKey);System.out.println(DATA + ">>>3DES 加密>>>"+ BytesToHex.fromBytesToHex(tridesResult));byte[] tridesPlain = TripleDESUtil.decrypt(tridesResult, tridesKey);System.out.println(DATA + ">>>3DES 解密>>>" + new String(tridesPlain));System.out.println(System.currentTimeMillis() - start);}
}