3DES & AES
3DES 介绍
上篇文章已经介绍了 DES 算法的使用,并且也提到,在计算机计算速度特别快的今天,要破解 DES 加密过后的数据是完全有可能做到的,为什么呢?因为 DES 算法的密钥 也就64位,所有可能性加在一起也就是 2^64 次方。所以 3DES 在 DES 的基础上进行了改进,把密钥的长度加长了,可以是 112 位或者 168 位,这样密钥的可能性就增加到了 2^112 或者 2^168,也就不可能再被破解了,但是这么做也是有缺点的,因为3DES 算法在增加密钥的同时也增加了迭代次数,这就会造成处理速度降低,加密效率比较低,这完全是牺牲时间和性能来提高安全性。
3DES 的加密模式和填充方式和 DES 算法中的一模一样,这里就不在多介绍。
3DES 的使用
其实 DES, 3DES , AES 这三种算法的使用都是基本相同的,都是先获取到密钥,然后利用 Cipher 类进行加密,解密过程和加密过程更是只有一词之差。下面来看看 3DES 的使用。
public class TripeDESUtil {
//初始化密钥
public static byte[] initKey() throws Exception{
KeyGenerator keyGen = KeyGenerator.getInstance("DESede");
keyGen.init(168);
SecretKey secretKey = keyGen.generateKey();
return secretKey.getEncoded();
}
//加密
public static byte[] encryptTripeDES(byte[] data,byte[] key) throws Exception{
SecretKey secretKey = new SecretKeySpec(key, "DESede");
Cipher cipher = Cipher.getInstance("DESede");
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
byte[] resultBytes = cipher.doFinal(data);
return resultBytes;
}
//解密
public static byte[] decryptTripeDES(byte[] src,byte[] key) throws Exception{
SecretKey secretKey = new SecretKeySpec(key, "DESede");
Cipher cipher = Cipher.getInstance("DESede");
cipher.init(Cipher.DECRYPT_MODE,secretKey);
byte[] resultBytes = cipher.doFinal(src);
return resultBytes;
}
}
将 byte 转化为 hex 的方法如下
public class Helper {
public static String fromByteToHex(byte[] data){
StringBuilder builder = new StringBuilder("");
if(data == null || data.length <= 0){
return null;
}
for(int i = 0; i<data.length;i++){
int v = data[i] & 0xFF;
String result = Integer.toHexString(v);
if(result.length()<2){
builder.append(0);
}
builder.append(result);
}
return builder.toString();
}
}
AES 介绍
AES 是高级加密标准,能够抵御已知的针对 DES 算法的所有攻击,而且相比于 3DES, 它的加密效率高,安全性能高。
AES 的加密模式和填充方式和 DES 是相同的,但是它的密钥有三种不同的长度,分别是 128(默认长度),192,256。不过需要注意的是,后两种长度的密钥默认状态下是不能使用的,只有在取得了相关政策权限才可以使用。
public class AESUtil {
public static byte[] initKey() throws Exception{
KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
keyGenerator.init(128);
SecretKey secretKey = keyGenerator.generateKey();
return secretKey.getEncoded();
}
public static byte[] encryptAES(byte[] data, byte[] key) throws Exception{
SecretKey secretKey = new SecretKeySpec(key, "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
byte[] resultBytes = cipher.doFinal(data);
return resultBytes;
}
public static byte[] decryptAES(byte[] src, byte[] key) throws Exception{
SecretKey secretKey = new SecretKeySpec(key, "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, secretKey);
byte[] resultBytes = cipher.doFinal(src);
return resultBytes;
}
}
以上使用的是密钥为 128 位的,现在尝试使用 192 位的
keyGenerator.init(192);
运行一下,出现了如下错误
Exception in thread "main" java.security.InvalidKeyException: Illegal key size or default parameters
at javax.crypto.Cipher.checkCryptoPerm(Cipher.java:1026)
at javax.crypto.Cipher.implInit(Cipher.java:801)
at javax.crypto.Cipher.chooseProvider(Cipher.java:864)
at javax.crypto.Cipher.init(Cipher.java:1249)
at javax.crypto.Cipher.init(Cipher.java:1186)
at com.hwaphon.AESUtil.encryptAES(AESUtil.java:27)
at com.hwaphon.Client.main(Client.java:23)
提示为非法的 key size,说明我们当前没有权限使用 192位的密钥,那么该怎么办呢?
先去 Oracle 官网下载文件 ,点击此处, 下载完毕之后解压出来,能够看到两个 JAR 包,复制,找到 JDK 的安装目录,到 jdk\jre\lib\security
目录下替换 JAR 文件,然后到 JRE 目录下,做同样的替换操作,即可使用。