1.先看下介绍
AES 密码学中的高级加密标准(Advanced Encryption Standard,AES),又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准。这个标准用来替代原先的DES(Data Encryption Standard),已经被多方分析且广为全世界所使用。
AES 是对称加密算法,优点:加密速度快;缺点:如果秘钥丢失,就容易解密密文,安全性相对比较差
对称加密 : 也就是加密秘钥和解密秘钥是一样的。
非对称加密 : 也就是加密秘钥和解密秘钥是不一样的。
2.废话不多说,直接上代码
2.1 自己定义的一个类,参数是AES加密模式,方便调用
public static final String AESCBCNoPadding = "AES/CBC/NoPadding";
public static final String AESCBCPKCS5Padding = "AES/CBC/PKCS5Padding(";
public static final String AESECBNoPadding = "AES/ECB/NoPadding";
public static final String AESECBPKCS5Padding = "AES/ECB/PKCS5Padding";
public static final String DESCBCNoPadding = "DES/CBC/NoPadding";
public static final String DESCBCPKCS5Padding = "DES/CBC/PKCS5Padding";
public static final String DESECBNoPadding = "DES/ECB/NoPadding";
public static final String DESECBPKCS5Padding = "DES/ECB/PKCS5Padding";
public static final String DESedeCBCNoPadding = "DESede/CBC/NoPadding";
public static final String DESedeCBCPKCS5Padding = "DESede/CBC/PKCS5Padding";
public static final String DESedeECBNoPadding = "DESede/ECB/NoPadding";
public static final String DESedeECBPKCS5Padding = "DESede/ECB/PKCS5Padding";
public static final String RSAECBPKCS1Padding = "RSA/ECB/PKCS1Padding";
public static final String RSAECBOAEPWithSHA_1AndMGF1Padding = "RSA/ECB/OAEPWithSHA-1AndMGF1Padding";
public static final String RSAECBOAEPWithSHA_256AndMGF1Padding = "RSA/ECB/OAEPWithSHA-256AndMGF1Padding";
2.2 由于aes加密后的字节数组,直接转String返回参数有可能存在乱码,所以对返回值做一下处理,将加密的结果转换为base64的字符串。同理,解密时候,需要把字符串先base64处理,再把解密后的内容进行aes解密操作。
也就是说流程为:
加密(从前往后):明文 -> 加密 -> base64处理 -> 密文
解密(从后往前):明文 <- 解密 <- base64处理 <- 密文
/**
* @param data 明文
* @param key 密钥,长度16
* @param iv 偏移量,长度16
* @return 密文
* @Description AES算法加密明文
*/
public static String AesEncrypt(String data, String key, String iv) {
try {
//AES/CBC/NoPadding
Cipher cipher = Cipher.getInstance(AESEnum.AESCBCNoPadding);
int blockSize = cipher.getBlockSize();
byte[] dataBytes = data.getBytes();
int plaintextLength = dataBytes.length;
if (plaintextLength % blockSize != 0) {
plaintextLength = plaintextLength + (blockSize - (plaintextLength % blockSize));
}
byte[] plaintext = new byte[plaintextLength];
System.arraycopy(dataBytes, 0, plaintext, 0, dataBytes.length);
SecretKeySpec keyspec = new SecretKeySpec(key.getBytes(), "AES");
// CBC模式,需要一个向量iv,可增加加密算法的强度
IvParameterSpec ivspec = new IvParameterSpec(iv.getBytes());
cipher.init(Cipher.ENCRYPT_MODE, keyspec, ivspec);
byte[] encrypted = cipher.doFinal(plaintext);
// 加密后直接转string可能乱码,用BASE64做转码。
return encode(encrypted).trim();
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* @param data 密文
* @param key 密钥,长度16
* @param iv 偏移量,长度16
* @return 明文
* @Description AES算法解密
*/
public static String AesDecrypt(String data, String key, String iv) {
try {
//先用base64解密
byte[] encrypted1 = decode(data);
//AES/CBC/NoPadding
Cipher cipher = Cipher.getInstance(AESEnum.AESCBCNoPadding);
SecretKeySpec keyspec = new SecretKeySpec(key.getBytes(), "AES");
IvParameterSpec ivspec = new IvParameterSpec(iv.getBytes());
cipher.init(Cipher.DECRYPT_MODE, keyspec, ivspec);
byte[] original = cipher.doFinal(encrypted1);
String originalString = new String(original);
return originalString.trim();
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 编码
*
* @param byteArray
* @return
*/
public static String encode(byte[] byteArray) {
return new String(new org.apache.commons.codec.binary.Base64().encode(byteArray));
}
/**
* 解码
*
* @param base64EncodedString
* @return
*/
public static byte[] decode(String base64EncodedString) {
return new org.apache.commons.codec.binary.Base64().decode(base64EncodedString);
}
用到的依赖
<!--常用的加密解密方法-->
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.15</version>
</dependency>
测试结果:
没一点问题滴