AES是对称性加密算法中最为流行的算法之一。
对于AES加密算法的流程,可以参考这篇博文:AES加密模式与填充
AES有5种模式,其中ECB模式是不安全的,已经废弃;CBC是APPLE默认的加密模式,所以我们也选用CBC来讲解。
我们用java的代码来举例AES算法的一些流程和细节问题:
public static String aesEncrypt(String plainText, String secret,String iv) {
try {
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
SecretKeySpec keySpec = new SecretKeySpec(secret.getBytes("utf-8"),"AES");
IvParameterSpec ivParameterSpec = new IvParameterSpec(iv.getBytes("utf-8"));
cipher.init(Cipher.ENCRYPT_MODE,keySpec,ivParameterSpec);
byte[] byteContent = plainText.getBytes("utf-8");
byte[] result = cipher.doFinal(byteContent);
String encryptText = Base64.getEncoder().encodeToString(result);
return encryptText;
} catch (Exception e) {
throw new RuntimeException(e.getMessage(), e);
}
}
结合上篇博文中的CBC模式图,可以看到:
1,初始化向量(iv)就好比随机数中的种子。
2,PKCS5Padding,因为AES的数据库用128位去切分,当最后的部分不足128位的时候,那么就需要进行填充来达到128位。
其中,AES对secret(密钥)和iv的长度有规定:
1,secret有128位,192位,256位。在java中,128位的AES是jdk自带的,但是大于128位的AES,则需要引入一个额外的security包。从线上运维来看,这可能会增加一定的复杂度,所以,我从个人角度上来看,128位足够,减少运维的复杂度。加密算法的安全在乎与密码是否安全保护好,而不在于是128位还是256位。
2,iv是128位的。
3,我们在输secret的时候,往往不会在乎多少长,比如任意长度的secret,而不会刚好128位,对于iv是同样的道理。那么我们可以采用下面的方式方法来简化这个流程:
String md5 = md5Hex(secret);
secret = md5.substring(0,15);
String iv = md5.substring(16);