java AES加密、解密
CreationTime--2018年7月14日10點06分
Author:Marydon
1.准備工作
updateTime--2018年8月10日15點28分
updateTime--2018年10月24日10點46分
import java.security.SecureRandom;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import org.apache.log4j.Logger;
import dzkjk.web.tools.ByteUtils;
/**
* AES加密算法工具類
* @explain 可逆算法:加密、解密
* AES/ECB/PKCS5Padding
* @author Marydon
* @creationTime 2018年7月7日下午2:17:43
* @version 3.0
* @since 2.0
* @email marydon20170307@163.com
*/
public class AESUtils {
private static Logger log = Logger.getLogger(AESUtils.class);
// 定義字符集
private static final String ENCODING = "UTF-8";
/**
* 根據提供的密鑰生成AES專用密鑰
* @explain
* @param password
* 可以是中文、英文、16進制字符串
* @return AES密鑰
* @throws Exception
*/
public static byte[] generateKey(String password) throws Exception {
byte[] keyByteArray = null;
// 創建AES的Key生產者
KeyGenerator kgen = KeyGenerator.getInstance("AES");
// 利用用戶密碼作為隨機數初始化
// 128位的key生產者
// 加密沒關系,SecureRandom是生成安全隨機數序列,password.getBytes()是種子,只要種子相同,序列就一樣,所以解密只要有password就行
/*
* 只適用windows
* kgen.init(128, new SecureRandom(password.getBytes(ENCODING)));
*/
// 指定強隨機數的生成方式
// 兼容linux
SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
random.setSeed(password.getBytes(ENCODING));
kgen.init(128, random);// 只能是128位
// 根據用戶密碼,生成一個密鑰
SecretKey secretKey = kgen.generateKey();
// 返回基本編碼格式的密鑰,如果此密鑰不支持編碼,則返回null。
keyByteArray = secretKey.getEncoded();
return keyByteArray;
}
}
2.AES加密
/**
* AES加密字符串
* @param content
* 需要被加密的字符串
* @param password
* 加密需要的密碼
* @return 16進制的密文(密文的長度隨着待加密字符串的長度變化而變化,至少32位)
*/
public static String encrypt(String content, String password) {
String cipherHexString = "";// 返回字符串
try {
// 轉換為AES專用密鑰
byte[] keyBytes = generateKey(password);
SecretKeySpec sks = new SecretKeySpec(keyBytes, "AES");
// 將待加密字符串轉二進制
byte[] clearTextBytes = content.getBytes(ENCODING);
// 創建密碼器
Cipher cipher = Cipher.getInstance("AES");
// 初始化為加密模式的密碼器
cipher.init(Cipher.ENCRYPT_MODE, sks);
// 加密結果
byte[] cipherTextBytes = cipher.doFinal(clearTextBytes);
// byte[]-->hexString
cipherHexString = ByteUtils.toHexString(cipherTextBytes);
} catch (Exception e) {
e.printStackTrace();
log.error("AES加密失敗:" + e.getMessage());
}
log.info("AES加密結果:" + cipherHexString);
return cipherHexString;
}
3.AES解密
/**
* 解密AES加密過的字符串
* @param content
* 16進制密文
* @param password
* 加密時的密碼
* @return 明文
*/
public static String decrypt(String hexString, String password) {
String clearText = "";
try {
// 轉換為AES專用密鑰
byte[] keyBytes = generateKey(password);
SecretKeySpec sks = new SecretKeySpec(keyBytes, "AES");
// 創建密碼器
Cipher cipher = Cipher.getInstance("AES");
// 初始化為解密模式的密碼器
cipher.init(Cipher.DECRYPT_MODE, sks);
// hexString-->byte[]
// 將16進制密文轉換成二進制
byte[] cipherTextBytes = ByteUtils.fromHexString(hexString);
// 解密結果
byte[] clearTextBytes = cipher.doFinal(cipherTextBytes);
// byte[]-->String
clearText = new String(clearTextBytes, ENCODING);
} catch (Exception e) {
e.printStackTrace();
log.error("AES解密失敗:" + e.getMessage());
}
log.info("AES解密結果:" + clearText);
return clearText;
}
4.測試
public static void main(String[] args) {
String json = "{\"name\":\"Marydon\",\"website\":\"http://www.cnblogs.com/Marydon20170307\"}";
String password = "測試";
// 加密
String encrypt = encrypt(json, password);
// 解密
String decrypt = decrypt(encrypt, password);
}
