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); }