正文
一、AES加密简介
AES加密算法是密码学中的高级加密标准(Advanced Encryption Standard,AES),又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准。这个标准用来替代原先的DES,已经被多方分析且广为全世界所使用。
AES 是一个新的可以用于保护电子数据的加密算法。明确地说,AES 是一个迭代的、对称密钥分组的密码,它可以使用128、192 和 256 位密钥,并且用 128 位(16字节)分组加密和解密数据。与公共密钥密码使用密钥对不同,对称密钥密码使用相同的密钥加密和解密数据。通过分组密码返回的加密数据 的位数与输入数据相同。迭代加密使用一个循环结构,在该循环中重复置换(permutations )和替换(substitutions)输入数据。
AES加密有很多轮的重复和变换。大致步骤如下:
1、密钥扩展(KeyExpansion)。
2、初始轮(Initial Round)。
3、重复轮(Rounds),每一轮又包括:SubBytes、ShiftRows、MixColumns、AddRoundKey。
4、最终轮(Final Round),最终轮没有MixColumns。
二、AES在JAVA中的使用
JCE,Java Cryptography Extension,在早期JDK版本中,由于受美国的密码出口条例约束,Java中涉及加解密功能的API被限制出口,所以Java中安全组件被分成了两部分: 不含加密功能的JCA(Java Cryptography Architecture )和含加密功能的JCE(Java Cryptography Extension)。
JCA和JCE的API体系架构
JCE的API都在javax.crypto包下,核心功能包括:加解密、密钥生成(对称)、MAC生成、密钥协商。
(1). 加解密
加解密功能由Cipher组件提供,其也是JCE中最核心的组件。
1. Cipher的几个知识点:
a. Cipher在使用时需以参数方式指定transformation
b. transformation的格式为algorithm/mode/padding,其中algorithm为必输项,如: AES/DES/CBC/PKCS5Padding
c. 缺省的mode为ECB,缺省的padding为PKCS5Padding
d. 在block算法与流加密模式组合时, 需在mode后面指定每次处理的bit数, 如DES/CFB8/NoPadding,
如未指定则使用缺省值, SunJCE缺省值为64bits
e. Cipher有4种操作模式: ENCRYPT_MODE(加密), DECRYPT_MODE(解密), WRAP_MODE(导出Key), UNWRAP_MODE(导入Key),初始化时需指定某种操作模式
[html]
view plain
copy
print
?
-
算法/模式/填充 16字节加密后数据长度 不满16字节加密后长度
-
AES/CBC/NoPadding 16 不支持
-
AES/CBC/PKCS5Padding 32 16
-
AES/CBC/ISO10126Padding 32 16
-
AES/CFB/NoPadding 16 原始数据长度
-
AES/CFB/PKCS5Padding 32 16
-
AES/CFB/ISO10126Padding 32 16
-
AES/ECB/NoPadding 16 不支持
-
AES/ECB/PKCS5Padding 32 16
-
AES/ECB/ISO10126Padding 32 16
-
AES/OFB/NoPadding 16 原始数据长度
-
AES/OFB/PKCS5Padding 32 16
-
AES/OFB/ISO10126Padding 32 16
-
AES/PCBC/NoPadding 16 不支持
-
AES/PCBC/PKCS5Padding 32 16
-
AES/PCBC/ISO10126Padding 32 16
算法/模式/填充 16字节加密后数据长度 不满16字节加密后长度
AES/CBC/NoPadding 16 不支持
AES/CBC/PKCS5Padding 32 16
AES/CBC/ISO10126Padding 32 16
AES/CFB/NoPadding 16 原始数据长度
AES/CFB/PKCS5Padding 32 16
AES/CFB/ISO10126Padding 32 16
AES/ECB/NoPadding 16 不支持
AES/ECB/PKCS5Padding 32 16
AES/ECB/ISO10126Padding 32 16
AES/OFB/NoPadding 16 原始数据长度
AES/OFB/PKCS5Padding 32 16
AES/OFB/ISO10126Padding 32 16
AES/PCBC/NoPadding 16 不支持
AES/PCBC/PKCS5Padding 32 16
AES/PCBC/ISO10126Padding 32 16
可以看到,在原始数据长度为16的整数倍时,假如原始数据长度等于16*n,则使用NoPadding时加密后数据长度等于16*n,其它情况下加密数据长 度等于16*(n+1)。在不足16的整数倍的情况下,假如原始数据长度等于16*n+m[其中m小于16],除了NoPadding填充之外的任何方 式,加密数据长度都等于16*(n+1);NoPadding填充情况下,CBC、ECB和PCBC三种模式是不支持的,CFB、OFB两种模式下则加密 数据长度等于原始数据长度。
2. 对称加密的算法与密钥长度选择
算法名称
|
密钥长
|
块长
|
速度
|
说明
|
DES 56
|
64
|
64
|
慢
|
不安全, 不要使用
|
3DES
|
112/168
|
64
|
很慢
|
中等安全, 适合加密较小的数据
|
AES
|
128, 192, 256
|
128
|
快
|
安全
|
Blowfish
|
(4至56)*8
|
64
|
快
|
快 应该安全, 在安全界尚未被充分分析、论证
|
RC4
|
40-1024
|
64
|
很快
|
安全性不明确
|
推荐使用AES算法。一般认为128bits的密钥已足够安全,如果可以请选择256bits的密钥。注意:
a. 密钥长度是在生成密钥时指定的,如:
[html]
view plain
copy
print
?
-
KeyGenerator generator = KeyGenerator.getInstance("AES/CBC/PKCS5PADDING");
-
generator.init(256);
-
SecretKey key = generator.generateKey();
KeyGenerator generator = KeyGenerator.getInstance("AES/CBC/PKCS5PADDING");
generator.init(256);
SecretKey key = generator.generateKey();
3. 加密示例代码
[html]
view plain
copy
print
?
-
/**
-
* 根据密钥对指定的明文plainText进行加密.
-
*
-
* @param plainText 明文
-
* @return 加密后的密文.
-
*/
-
public static final String encrypt(String plainText) {
-
Key secretKey = getKey("fendo888");
-
try {
-
Cipher cipher = Cipher.getInstance("AES");
-
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
-
byte[] p = plainText.getBytes("UTF-8");
-
byte[] result = cipher.doFinal(p);
-
BASE64Encoder encoder = new BASE64Encoder();
-
String encoded = encoder.encode(result);
-
return encoded;
-
} catch (Exception e) {
-
throw new RuntimeException(e);
-
}
-
}
/**
* 根据密钥对指定的明文plainText进行加密.
*
* @param plainText 明文
* @return 加密后的密文.
*/
public static final String encrypt(String plainText) {
Key secretKey = getKey("fendo888");
try {
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
byte[] p = plainText.getBytes("UTF-8");
byte[] result = cipher.doFinal(p);
BASE64Encoder encoder = new BASE64Encoder();
String encoded = encoder.encode(result);
return encoded;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
4. 解密示例代码
[html]
view plain
copy
print
?
-
/**
-
* 根据密钥对指定的密文cipherText进行解密.
-
*
-
* @param cipherText 密文
-
* @return 解密后的明文.
-
*/
-
public static final String decrypt(String cipherText) {
-
Key secretKey = getKey("fendo888");
-
try {
-
Cipher cipher = Cipher.getInstance("AES");
-
cipher.init(Cipher.DECRYPT_MODE, secretKey);
-
BASE64Decoder decoder = new BASE64Decoder();
-
byte[] c = decoder.decodeBuffer(cipherText);
-
byte[] result = cipher.doFinal(c);
-
String plainText = new String(result, "UTF-8");
-
return plainText;
-
} catch (Exception e) {
-
throw new RuntimeException(e);
-
}
-
}
/**
* 根据密钥对指定的密文cipherText进行解密.
*
* @param cipherText 密文
* @return 解密后的明文.
*/
public static final String decrypt(String cipherText) {
Key secretKey = getKey("fendo888");
try {
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, secretKey);
BASE64Decoder decoder = new BASE64Decoder();
byte[] c = decoder.decodeBuffer(cipherText);
byte[] result = cipher.doFinal(c);
String plainText = new String(result, "UTF-8");
return plainText;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
其中的getKey()
[html]
view plain
copy
print
?
-
public static Key getKey(String keySeed) {
-
if (keySeed == null) {
-
keySeed = System.getenv("AES_SYS_KEY");
-
}
-
if (keySeed == null) {
-
keySeed = System.getProperty("AES_SYS_KEY");
-
}
-
if (keySeed == null || keySeed.trim().length() == 0) {
-
keySeed = "abcd1234!@#$";// 默认种子
-
}
-
try {
-
SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
-
secureRandom.setSeed(keySeed.getBytes());
-
KeyGenerator generator = KeyGenerator.getInstance("AES");
-
generator.init(secureRandom);
-
return generator.generateKey();
-
} catch (Exception e) {
-
throw new RuntimeException(e);
-
}
-
}
public static Key getKey(String keySeed) {
if (keySeed == null) {
keySeed = System.getenv("AES_SYS_KEY");
}
if (keySeed == null) {
keySeed = System.getProperty("AES_SYS_KEY");
}
if (keySeed == null || keySeed.trim().length() == 0) {
keySeed = "abcd1234!@#$";// 默认种子
}
try {
SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
secureRandom.setSeed(keySeed.getBytes());
KeyGenerator generator = KeyGenerator.getInstance("AES");
generator.init(secureRandom);
return generator.generateKey();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
三.AESUtils帮助类
[html]
view plain
copy
print
?
-
package com.fendo.MD5;
-
-
import java.io.IOException;
-
import java.io.UnsupportedEncodingException;
-
import java.security.InvalidKeyException;
-
import java.security.NoSuchAlgorithmException;
-
import java.security.SecureRandom;
-
-
import javax.crypto.BadPaddingException;
-
import javax.crypto.Cipher;
-
import javax.crypto.IllegalBlockSizeException;
-
import javax.crypto.KeyGenerator;
-
import javax.crypto.NoSuchPaddingException;
-
import javax.crypto.SecretKey;
-
import javax.crypto.spec.SecretKeySpec;
-
-
import org.apache.commons.lang3.StringUtils;
-
-
import sun.misc.BASE64Decoder;
-
import sun.misc.BASE64Encoder;
-
-
/**
-
* @Title: AESUtils.java
-
* @Package com.fendo.MD5
-
* @Description: TODO
-
* @author fendo
-
* @date 2017年9月11日 下午5:48:17
-
* @version V1.0
-
*/
-
public class AESUtils {
-
-
-
private static final String encodeRules = "fendo";
-
-
/**
-
* 加密
-
* 1.构造密钥生成器
-
* 2.根据ecnodeRules规则初始化密钥生成器
-
* 3.产生密钥
-
* 4.创建和初始化密码器
-
* 5.内容加密
-
* 6.返回字符串
-
*/
-
public static String AESEncode(String content) {
-
try {
-
//1.构造密钥生成器,指定为AES算法,不区分大小写
-
KeyGenerator keygen = KeyGenerator.getInstance("AES");
-
//2.根据ecnodeRules规则初始化密钥生成器
-
//生成一个128位的随机源,根据传入的字节数组
-
SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
-
random.setSeed(encodeRules.getBytes());
-
keygen.init(128, random);
-
//3.产生原始对称密钥
-
SecretKey original_key = keygen.generateKey();
-
//4.获得原始对称密钥的字节数组
-
byte[] raw = original_key.getEncoded();
-
//5.根据字节数组生成AES密钥
-
SecretKey key = new SecretKeySpec(raw, "AES");
-
//6.根据指定算法AES自成密码器
-
Cipher cipher = Cipher.getInstance("AES");
-
//7.初始化密码器,第一个参数为加密(Encrypt_mode)或者解密解密(Decrypt_mode)操作,第二个参数为使用的KEY
-
cipher.init(Cipher.ENCRYPT_MODE, key);
-
//8.获取加密内容的字节数组(这里要设置为utf-8)不然内容中如果有中文和英文混合中文就会解密为乱码
-
byte[] byte_encode = content.getBytes("utf-8");
-
//9.根据密码器的初始化方式--加密:将数据加密
-
byte[] byte_AES = cipher.doFinal(byte_encode);
-
//10.将加密后的数据转换为字符串
-
//这里用Base64Encoder中会找不到包
-
//解决办法:
-
//在项目的Build path中先移除JRE System Library,再添加库JRE System Library,重新编译后就一切正常了。
-
String AES_encode = new String(new BASE64Encoder().encode(byte_AES));
-
//11.将字符串返回
-
return AES_encode;
-
} catch (NoSuchAlgorithmException e) {
-
e.printStackTrace();
-
} catch (NoSuchPaddingException e) {
-
e.printStackTrace();
-
} catch (InvalidKeyException e) {
-
e.printStackTrace();
-
} catch (IllegalBlockSizeException e) {
-
e.printStackTrace();
-
} catch (BadPaddingException e) {
-
e.printStackTrace();
-
} catch (UnsupportedEncodingException e) {
-
e.printStackTrace();
-
}
-
//如果有错就返加nulll
-
return null;
-
}
-
-
-
-
/**
-
* AES加密
-
* @param content 待加密的内容
-
* @param encryptKey 加密密钥
-
* @return 加密后的byte[]
-
* @throws Exception
-
*/
-
public static byte[] aesEncryptToBytes(String content, String encryptKey) throws Exception {
-
KeyGenerator kgen = KeyGenerator.getInstance("AES");
-
kgen.init(128, new SecureRandom(encryptKey.getBytes()));
-
-
Cipher cipher = Cipher.getInstance("AES");
-
cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(kgen.generateKey().getEncoded(), "AES"));
-
-
return cipher.doFinal(content.getBytes("utf-8"));
-
}
-
-
/**
-
* 解密
-
* 解密过程:
-
* 1.同加密1-4步
-
* 2.将加密后的字符串反纺成byte[]数组
-
* 3.将加密内容解密
-
*/
-
public static String AESDecode(String content) {
-
try {
-
//1.构造密钥生成器,指定为AES算法,不区分大小写
-
KeyGenerator keygen = KeyGenerator.getInstance("AES");
-
//2.根据ecnodeRules规则初始化密钥生成器
-
//生成一个128位的随机源,根据传入的字节数组
-
SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
-
random.setSeed(encodeRules.getBytes());
-
keygen.init(128, random);
-
//3.产生原始对称密钥
-
SecretKey original_key = keygen.generateKey();
-
//4.获得原始对称密钥的字节数组
-
byte[] raw = original_key.getEncoded();
-
//5.根据字节数组生成AES密钥
-
SecretKey key = new SecretKeySpec(raw, "AES");
-
//6.根据指定算法AES自成密码器
-
Cipher cipher = Cipher.getInstance("AES");
-
//7.初始化密码器,第一个参数为加密(Encrypt_mode)或者解密(Decrypt_mode)操作,第二个参数为使用的KEY
-
cipher.init(Cipher.DECRYPT_MODE, key);
-
//8.将加密并编码后的内容解码成字节数组
-
byte[] byte_content = new BASE64Decoder().decodeBuffer(content);
-
/*
-
* 解密
-
*/
-
byte[] byte_decode = cipher.doFinal(byte_content);
-
String AES_decode = new String(byte_decode, "utf-8");
-
return AES_decode;
-
} catch (NoSuchAlgorithmException e) {
-
e.printStackTrace();
-
} catch (NoSuchPaddingException e) {
-
e.printStackTrace();
-
} catch (InvalidKeyException e) {
-
e.printStackTrace();
-
} catch (IOException e) {
-
e.printStackTrace();
-
} catch (IllegalBlockSizeException e) {
-
e.printStackTrace();
-
} catch (BadPaddingException e) {
-
e.printStackTrace();
-
}
-
//如果有错就返加nulll
-
return null;
-
}
-
-
-
/**
-
* AES解密
-
* @param encryptBytes 待解密的byte[]
-
* @param decryptKey 解密密钥
-
* @return 解密后的String
-
* @throws Exception
-
*/
-
public static String aesDecryptByBytes(byte[] encryptBytes, String decryptKey) throws Exception {
-
KeyGenerator kgen = KeyGenerator.getInstance("AES");
-
kgen.init(128, new SecureRandom(decryptKey.getBytes()));
-
-
Cipher cipher = Cipher.getInstance("AES");
-
cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(kgen.generateKey().getEncoded(), "AES"));
-
byte[] decryptBytes = cipher.doFinal(encryptBytes);
-
-
return new String(decryptBytes);
-
}
-
-
/**
-
* base 64 加密
-
* @param bytes 待编码的byte[]
-
* @return 编码后的base 64 code
-
*/
-
public static String base64Encode(byte[] bytes){
-
return new BASE64Encoder().encode(bytes);
-
}
-
-
/**
-
* base 64 解密
-
* @param base64Code 待解码的base 64 code
-
* @return 解码后的byte[]
-
* @throws Exception
-
*/
-
public static byte[] base64Decode(String base64Code) throws Exception{
-
return StringUtils.isEmpty(base64Code) ? null : new BASE64Decoder().decodeBuffer(base64Code);
-
}
-
-
/**
-
* 将base 64 code AES解密
-
* @param encryptStr 待解密的base 64 code
-
* @param decryptKey 解密密钥
-
* @return 解密后的string
-
* @throws Exception
-
*/
-
public static String aesDecrypt(String encryptStr, String decryptKey) throws Exception {
-
return StringUtils.isEmpty(encryptStr) ? null : aesDecryptByBytes(base64Decode(encryptStr), decryptKey);
-
}
-
-
/**
-
* AES加密为base 64 code
-
* @param content 待加密的内容
-
* @param encryptKey 加密密钥
-
* @return 加密后的base 64 code
-
* @throws Exception
-
*/
-
public static String aesEncrypt(String content, String encryptKey) throws Exception {
-
return base64Encode(aesEncryptToBytes(content, encryptKey));
-
}
-
-
public static void main(String[] args) {
-
String[] keys = {
-
"", "root"
-
};
-
System.out.println("key | AESEncode | AESDecode");
-
for (String key : keys) {
-
System.out.print("key:"+key + " | ");
-
String encryptString = AESEncode(key);
-
System.out.print(encryptString + " | ");
-
String decryptString = AESDecode(encryptString);
-
System.out.println(decryptString);
-
}
-
}
-
}
package com.fendo.MD5;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.lang3.StringUtils;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
/**
* @Title: AESUtils.java
* @Package com.fendo.MD5
* @Description: TODO
* @author fendo
* @date 2017年9月11日 下午5:48:17
* @version V1.0
*/
public class AESUtils {
private static final String encodeRules = "fendo";
/**
* 加密
* 1.构造密钥生成器
* 2.根据ecnodeRules规则初始化密钥生成器
* 3.产生密钥
* 4.创建和初始化密码器
* 5.内容加密
* 6.返回字符串
*/
public static String AESEncode(String content) {
try {
//1.构造密钥生成器,指定为AES算法,不区分大小写
KeyGenerator keygen = KeyGenerator.getInstance("AES");
//2.根据ecnodeRules规则初始化密钥生成器
//生成一个128位的随机源,根据传入的字节数组
SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
random.setSeed(encodeRules.getBytes());
keygen.init(128, random);
//3.产生原始对称密钥
SecretKey original_key = keygen.generateKey();
//4.获得原始对称密钥的字节数组
byte[] raw = original_key.getEncoded();
//5.根据字节数组生成AES密钥
SecretKey key = new SecretKeySpec(raw, "AES");
//6.根据指定算法AES自成密码器
Cipher cipher = Cipher.getInstance("AES");
//7.初始化密码器,第一个参数为加密(Encrypt_mode)或者解密解密(Decrypt_mode)操作,第二个参数为使用的KEY
cipher.init(Cipher.ENCRYPT_MODE, key);
//8.获取加密内容的字节数组(这里要设置为utf-8)不然内容中如果有中文和英文混合中文就会解密为乱码
byte[] byte_encode = content.getBytes("utf-8");
//9.根据密码器的初始化方式--加密:将数据加密
byte[] byte_AES = cipher.doFinal(byte_encode);
//10.将加密后的数据转换为字符串
//这里用Base64Encoder中会找不到包
//解决办法:
//在项目的Build path中先移除JRE System Library,再添加库JRE System Library,重新编译后就一切正常了。
String AES_encode = new String(new BASE64Encoder().encode(byte_AES));
//11.将字符串返回
return AES_encode;
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
//如果有错就返加nulll
return null;
}
/**
* AES加密
* @param content 待加密的内容
* @param encryptKey 加密密钥
* @return 加密后的byte[]
* @throws Exception
*/
public static byte[] aesEncryptToBytes(String content, String encryptKey) throws Exception {
KeyGenerator kgen = KeyGenerator.getInstance("AES");
kgen.init(128, new SecureRandom(encryptKey.getBytes()));
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(kgen.generateKey().getEncoded(), "AES"));
return cipher.doFinal(content.getBytes("utf-8"));
}
/**
* 解密
* 解密过程:
* 1.同加密1-4步
* 2.将加密后的字符串反纺成byte[]数组
* 3.将加密内容解密
*/
public static String AESDecode(String content) {
try {
//1.构造密钥生成器,指定为AES算法,不区分大小写
KeyGenerator keygen = KeyGenerator.getInstance("AES");
//2.根据ecnodeRules规则初始化密钥生成器
//生成一个128位的随机源,根据传入的字节数组
SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
random.setSeed(encodeRules.getBytes());
keygen.init(128, random);
//3.产生原始对称密钥
SecretKey original_key = keygen.generateKey();
//4.获得原始对称密钥的字节数组
byte[] raw = original_key.getEncoded();
//5.根据字节数组生成AES密钥
SecretKey key = new SecretKeySpec(raw, "AES");
//6.根据指定算法AES自成密码器
Cipher cipher = Cipher.getInstance("AES");
//7.初始化密码器,第一个参数为加密(Encrypt_mode)或者解密(Decrypt_mode)操作,第二个参数为使用的KEY
cipher.init(Cipher.DECRYPT_MODE, key);
//8.将加密并编码后的内容解码成字节数组
byte[] byte_content = new BASE64Decoder().decodeBuffer(content);
/*
* 解密
*/
byte[] byte_decode = cipher.doFinal(byte_content);
String AES_decode = new String(byte_decode, "utf-8");
return AES_decode;
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
}
//如果有错就返加nulll
return null;
}
/**
* AES解密
* @param encryptBytes 待解密的byte[]
* @param decryptKey 解密密钥
* @return 解密后的String
* @throws Exception
*/
public static String aesDecryptByBytes(byte[] encryptBytes, String decryptKey) throws Exception {
KeyGenerator kgen = KeyGenerator.getInstance("AES");
kgen.init(128, new SecureRandom(decryptKey.getBytes()));
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(kgen.generateKey().getEncoded(), "AES"));
byte[] decryptBytes = cipher.doFinal(encryptBytes);
return new String(decryptBytes);
}
/**
* base 64 加密
* @param bytes 待编码的byte[]
* @return 编码后的base 64 code
*/
public static String base64Encode(byte[] bytes){
return new BASE64Encoder().encode(bytes);
}
/**
* base 64 解密
* @param base64Code 待解码的base 64 code
* @return 解码后的byte[]
* @throws Exception
*/
public static byte[] base64Decode(String base64Code) throws Exception{
return StringUtils.isEmpty(base64Code) ? null : new BASE64Decoder().decodeBuffer(base64Code);
}
/**
* 将base 64 code AES解密
* @param encryptStr 待解密的base 64 code
* @param decryptKey 解密密钥
* @return 解密后的string
* @throws Exception
*/
public static String aesDecrypt(String encryptStr, String decryptKey) throws Exception {
return StringUtils.isEmpty(encryptStr) ? null : aesDecryptByBytes(base64Decode(encryptStr), decryptKey);
}
/**
* AES加密为base 64 code
* @param content 待加密的内容
* @param encryptKey 加密密钥
* @return 加密后的base 64 code
* @throws Exception
*/
public static String aesEncrypt(String content, String encryptKey) throws Exception {
return base64Encode(aesEncryptToBytes(content, encryptKey));
}
public static void main(String[] args) {
String[] keys = {
"", "root"
};
System.out.println("key | AESEncode | AESDecode");
for (String key : keys) {
System.out.print("key:"+key + " | ");
String encryptString = AESEncode(key);
System.out.print(encryptString + " | ");
String decryptString = AESDecode(encryptString);
System.out.println(decryptString);
}
}
}