一 什么是三重DES
三重DES是为了增加DES的强度,将DES重复3次所得到的一种密码算法,通常缩写为3DES。
二 三重DSE加密
明文经过三次DES处理才能变成最后的密文,由于DES密钥长度实质是56位,因此3DES的密钥长度就是56*3=168比特。
注意:三重DES的三次DES加密是(加密->解密->加密),而不是(加密->加密->加密),为什么这样设计呢?看看下面这张图就明白了。
如果三次DES加密的密钥都相同,前两次DES,相当于还原成了密文,这样看来,真正起作用的只是最后一次。这样做的好处是:三重DES对DES具备向下兼容性。
还有一种密码叫DES-EDE2,下面我们用图来描述这一种密码。
当然,只有三个密钥互不相等才是正宗的DES-EDE3。
三 三重DES解密
三重DES的解密过程和加密过程正好相反,是以密钥3、密钥2、密钥1的顺序执行解密->加密->解密的操作。
四 三重DES现状
尽管三重DES目前还被银行等机构使用,但其处理速度不高,除了特别重视向下兼容性的情况外,很少被用于新的用途。
代码实现
public class DESUtils {
private static final String KEY = "S)a5000a67a94#7&94802a75";
private static final String ALGORITHM = "desede/CBC/PKCS5Padding";
private static final String CHARSETNAME = "UTF-8";
// 向量 可有可无 终端后台也要约定
private final static String iv = "01234567";
/**
* 加密
* @param cleartext 明文
* @throws Exception
*/
public static String encrypt(String cleartext) throws Exception {
// 生成密钥KEY
byte[] rawKey = KEY.getBytes(CHARSETNAME);
byte[] clear = cleartext.getBytes(CHARSETNAME);
return Base64.encodeToString(encrypt(rawKey, clear), Base64.DEFAULT);
}
/**
* 解密
*
* @param encrypted 密文
* @throws Exception
*/
public static String decrypt(String encrypted) throws Exception {
// 生成密钥KEY
byte[] rawKey = KEY.getBytes(CHARSETNAME);
byte[] clear = Base64.decode(encrypted.getBytes(CHARSETNAME), Base64.DEFAULT);
return decrypt(rawKey, clear);
}
private static byte[] encrypt(byte[] raw, byte[] clear) throws Exception {
// KEY转换
DESedeKeySpec keySpecSpec = new DESedeKeySpec(raw);
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("desede");
Key desKey = keyFactory.generateSecret(keySpecSpec);
// 加密
Cipher cipher = Cipher.getInstance(ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, desKey, new IvParameterSpec(iv.getBytes()));
return cipher.doFinal(clear);
}
private static String decrypt(byte[] raw, byte[] encrypted) throws Exception {
// KEY转换
DESedeKeySpec keySpecSpec = new DESedeKeySpec(raw);
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("desede");
Key desKey = keyFactory.generateSecret(keySpecSpec);
// 解密
Cipher cipher = Cipher.getInstance(ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, desKey, new IvParameterSpec(iv.getBytes()));
return new String(cipher.doFinal(encrypted), CHARSETNAME);
}
}