AES 是 Advanced Encryption Standard 的缩写,也就是 高级加密标准 。具体可以见: 高级加密标准 。本文主要讨论使用 Java SDK中对 AES 的实现。
从 JDK 的 Cipher 文档 中,知道它支持 4 种 AES 加密模式:
AES 是一种加解密算法,那么 CBC, ECB, NoPadding 和 PKCS5Padding 是什么呢?
CBC, CBC 是分组密码工作模式,是对于按块处理密码的加密方式的一种扩充。NoPadding, PKCS5Padding 是填充(Padding),是对需要按块处理的数据,当数据长度不符合块处理需求时,按照一定方法填充满块长的一种规则。
关于分组密码工作模式,可以参考: 分组密码工作模式 和 AES五种加密模式(CBC、ECB、CTR、OCF、CFB)
关于填充,可以参考: Padding (cryptography)
参考, JAVA AES算法 知道(以下部分的内容为该文章里的内容):
import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import java.security.SecureRandom; import java.util.Base64; public class AesUtil{ /** * AES/CBC/PKCS5Padding加密,然后进行base64加密 * * @param plainText * @param key * @return * @throws Exception */ public static String encryptBase64AESCBC(String plainText, String key)throws Exception { byte[] clean = plainText.getBytes(); //Cipher Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); // Generating IV. int ivSize = cipher.getBlockSize(); byte[] iv = new byte[ivSize]; SecureRandom random = new SecureRandom(); random.nextBytes(iv); IvParameterSpec ivParameterSpec = new IvParameterSpec(iv); // Encrypt. SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes("UTF-8"), "AES"); cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec); byte[] encrypted = cipher.doFinal(clean); // Combine IV and encrypted part. byte[] encryptedIVAndText = new byte[ivSize + encrypted.length]; System.arraycopy(iv, 0, encryptedIVAndText, 0, ivSize); System.arraycopy(encrypted, 0, encryptedIVAndText, ivSize, encrypted.length); return Base64.getEncoder().encodeToString(encryptedIVAndText); } /** * base64解密后再进行AES/CBC/PKCS5Padding解密 * * @param encryptedIvText * @param key * @return * @throws Exception */ public static String decryptBase64AESCBC(String encryptedIvText, String key)throws Exception { byte[] encryptedIvTextBytes = Base64.getDecoder().decode(encryptedIvText); //Cipher Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); // Extract IV. int ivSize = cipher.getBlockSize(); byte[] iv = new byte[ivSize]; System.arraycopy(encryptedIvTextBytes, 0, iv, 0, iv.length); IvParameterSpec ivParameterSpec = new IvParameterSpec(iv); // Extract encrypted part. int encryptedSize = encryptedIvTextBytes.length - ivSize; byte[] encryptedBytes = new byte[encryptedSize]; System.arraycopy(encryptedIvTextBytes, ivSize, encryptedBytes, 0, encryptedSize); // Decrypt. SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes("UTF-8"), "AES"); cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec); byte[] original = cipher.doFinal(encryptedBytes); String originalString = new String(original); return originalString; } }
以上代码中 iv
的长度为 cipher.getBlockSize()
,然后将 iv
放在加密文本的前部分。解密的时候一样先获得 iv
,再进行加密内容的解密。