package com.nova.sankuai.domain.api.externalInterface.yxqb; import com.google.common.base.Charsets; import com.google.common.base.Strings; import com.nova.sankuai.infra.utils.Base64Utils; import org.apache.tomcat.util.codec.binary.Base64; import javax.crypto.Cipher; import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; /** * @Author Lilinhong * @Date 2022/7/7 17:32 */ public class AESUtil { /** * 生成128位随机密钥 */ public static byte[] randomKey() { return randomKey(128); } /** * 生成随机密钥 * * @param keySize 密钥位数 */ private static byte[] randomKey(int keySize) { if (keySize != 128) { throw new RuntimeException("AES密钥长度不合法. keySize:" + keySize); } KeyGenerator kg = null; try { kg = KeyGenerator.getInstance("AES"); } catch (NoSuchAlgorithmException e) { throw new RuntimeException(e); } kg.init(keySize, new SecureRandom()); // kg.init(keySize); byte[] key = kg.generateKey().getEncoded(); return key; } /** * 加密数据 * * @param data 待加密数据 * @param key 密钥 */ public static byte[] encrypt(byte[] data, byte[] key) throws Exception { if (key.length != 16) { throw new RuntimeException("AES加密失败, 密钥不是128位"); } Cipher cipher = Cipher.getInstance("AES"); SecretKeySpec keySpec = new SecretKeySpec(key, "AES"); cipher.init(Cipher.ENCRYPT_MODE, keySpec); return cipher.doFinal(data); } /** * 解密数据 * * @param value 待解密数据 * @param key 密钥 */ public static byte[] decrypt(byte[] value, byte[] key) throws Exception { if (key.length != 16) { throw new RuntimeException("AES解密失败, 密钥不是128位"); } Cipher cipher = Cipher.getInstance("AES"); SecretKey keySpec = new SecretKeySpec(key, "AES"); cipher.init(Cipher.DECRYPT_MODE, keySpec); return cipher.doFinal(value); } /** * 默认的AES加密字符串方法,可以内部使用 * 对明文的UTF-8编码字节进行加密,然后使用Base64转码 * 密钥使用UTF-8编码 * * @param data 明文 * @param key 加密密钥 */ public static String encrypt(String data, String key) throws Exception { if (Strings.isNullOrEmpty(data) || Strings.isNullOrEmpty(key)) { throw new RuntimeException("AES加密失败, 参数有误. data: " + data + ", key: " + key); } byte[] keyBytes = key.getBytes(Charsets.UTF_8); byte[] dataBytes = data.getBytes(Charsets.UTF_8); byte[] encryptBytes = encrypt(dataBytes, keyBytes); return Base64Utils.encode(encryptBytes); } /** * 默认的AES解密字符串方法,可以内部使用 * 对密文使用Base64转码后,再进行解密,然后再转为UTF-8编码 * 密钥使用UTF-8编码 * * @param ciphertext 密文 * @param key 加密密钥 */ public static String decrypt(String ciphertext, String key) throws Exception { if (Strings.isNullOrEmpty(ciphertext) || Strings.isNullOrEmpty(key)) { throw new RuntimeException("AES解密失败, 参数有误. ciphertext: " + ciphertext + ", key: " + key); } byte[] keyBytes = key.getBytes(Charsets.UTF_8); byte[] dataBytes = com.nova.sankuai.infra.utils.Base64Utils.decode(ciphertext); byte[] keyBytesDecrypt = decrypt(dataBytes, keyBytes); return new String(keyBytesDecrypt, Charsets.UTF_8); } public static void main(String[] args) throws Exception { try { KeyGenerator kg = KeyGenerator.getInstance("AES"); //下面调用方法的参数决定了生成密钥的长度,可以修改为128, 192或256 kg.init(128); SecretKey sk = kg.generateKey(); byte[] b = sk.getEncoded(); String secret = Base64.encodeBase64String(b); System.out.println(secret); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); throw new RuntimeException("没有此算法"); } // System.out.println(AESUtil.encrypt("都送给了返回观看链接", "1234567890asdfgh")); System.out.println(AESUtil.encrypt("都送给了返回观看链接", "M+g4NLb8yotZfSHv")); // System.out.println(AESUtil.decrypt("KvjpPd24UwoGoq6zTzIsURkv+wvkJ9R77eFFtYqKv5M=", "M+g4NLb8yotZfSHv")); System.out.println(AESUtil.decrypt("FcNqD7PH/jOCg75OM1SeDWDpkcBE4ZvKHfzEFZ+wuyM=", "M+g4NLb8yotZfSHv")); } }