package ink.wgink.util; import org.apache.commons.codec.binary.Base64; import org.apache.commons.codec.binary.StringUtils; import org.bouncycastle.jce.provider.BouncyCastleProvider; import javax.crypto.Cipher; import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import java.security.SecureRandom; import java.security.Security; public class AesUtil { private static final String IV_STRING = "16-Bytes--String"; /** * PKCS#7 */ public static final String PKCS_7 = "PKCS7Padding"; /** * PKCS#5 */ public static final String PKCS_5 = "PKCS5Padding"; /** * AES加密 * * @param encodeRule * @param content * @return * @throws Exception */ public static String aesEncoder(String encodeRule, String content) { try { // 1.构造秘钥生成器 KeyGenerator keyGenerator = KeyGenerator.getInstance("AES"); // 2.根据编码规则构建秘钥生成器 SecureRandom random = SecureRandom.getInstance("SHA1PRNG"); random.setSeed(encodeRule.getBytes()); keyGenerator.init(128, random); // 3.产生堆成秘钥 SecretKey secretKey = keyGenerator.generateKey(); // 4.对称秘钥原始数组 byte[] secretKeyByte = secretKey.getEncoded(); // 5.生成AES秘钥 SecretKey key = new SecretKeySpec(secretKeyByte, "AES"); // 6.初始化密码器 Cipher cipher = Cipher.getInstance("AES"); cipher.init(Cipher.ENCRYPT_MODE, key); // 8.获取加密内容字节数组 byte[] contentByte = content.getBytes("UTF-8"); // 9.加密 return new String(Base64.encodeBase64(cipher.doFinal(contentByte))); } catch (Exception e) { throw new AesEncodeException(e.getMessage(), e); } } /** * AES解密 * * @param encodeRule * @param content * @return */ public static String aesDecoder(String encodeRule, String content) { try { // 1.构建秘钥生成器 KeyGenerator keyGenerator = KeyGenerator.getInstance("AES"); // 2.根据编码规则构建秘钥生成器 SecureRandom random = SecureRandom.getInstance("SHA1PRNG"); random.setSeed(encodeRule.getBytes()); keyGenerator.init(128, random); // 3.生成对称解密秘钥 SecretKey secretKey = keyGenerator.generateKey(); // 4.对称秘钥原始数组 byte[] secretKeyByte = secretKey.getEncoded(); // 5.生成AES秘钥 SecretKey key = new SecretKeySpec(secretKeyByte, "AES"); // 6.初始化密码器 Cipher cipher = Cipher.getInstance("AES"); cipher.init(Cipher.DECRYPT_MODE, key); // 7.要解密内容的字节数组 byte[] contentByte = Base64.decodeBase64(content); // 8.解密 return new String(cipher.doFinal(contentByte), "UTF-8"); } catch (Exception e) { throw new AesDecodeException(e.getMessage(), e); } } /** * 通用aes加密,兼容IOS * * @param key * @param content * @return */ public static String aesCommonEncoder(String key, String content) { try { byte[] encryptedBytes = aesCommonEncodeDetail(key, content, IV_STRING.getBytes(), PKCS_5); return new String(Base64.encodeBase64(encryptedBytes), "UTF-8"); } catch (Exception e) { throw new AesEncodeException(e.getMessage(), e); } } /** * 通用aes加密,兼容IOS * * @param key * @param content * @param paddingType * @return */ public static byte[] aesCommonEncodeDetail(String key, String content, byte[] ivBytes, String paddingType) { try { byte[] byteContent = content.getBytes("UTF-8"); byte[] enCodeFormat = key.getBytes(); SecretKeySpec secretKeySpec = new SecretKeySpec(enCodeFormat, "AES"); IvParameterSpec ivParameterSpec = new IvParameterSpec(ivBytes); if (StringUtils.equals(paddingType, PKCS_7)) { Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider()); } Cipher cipher = Cipher.getInstance("AES/CBC/" + paddingType); cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec); return cipher.doFinal(byteContent); } catch (Exception e) { throw new AesEncodeException(e.getMessage(), e); } } /** * aes通用解密,兼容IOS * * @param key * @param content * @return * @throws Exception */ public static String aesCommonDecoder(String key, String content) { try { byte[] encryptedBytes = Base64.decodeBase64(content); byte[] keyBytes = key.getBytes(); byte[] result = aesCommonDecoderDetail(keyBytes, encryptedBytes, IV_STRING.getBytes(), PKCS_5); return new String(result, "UTF-8"); } catch (Exception e) { throw new AesDecodeException(e.getMessage(), e); } } /** * aes cbc 通用解密 * * @param keyBytes 秘钥字节数组 * @param encryptedBytes 密文字节数组 * @param ivBytes 向量字节数组 * @param paddingType 填充类型 * @return */ public static byte[] aesCommonDecoderDetail(byte[] keyBytes, byte[] encryptedBytes, byte[] ivBytes, String paddingType) { try { SecretKeySpec secretKey = new SecretKeySpec(keyBytes, "AES"); IvParameterSpec ivParameterSpec = new IvParameterSpec(ivBytes); Cipher cipher; if (StringUtils.equals(paddingType, PKCS_7)) { Security.addProvider(new BouncyCastleProvider()); } cipher = Cipher.getInstance("AES/CBC/" + paddingType); cipher.init(Cipher.DECRYPT_MODE, secretKey, ivParameterSpec); return cipher.doFinal(encryptedBytes); } catch (Exception e) { throw new AesDecodeException(e.getMessage(), e); } } /** * AES解密异常 */ public static class AesDecodeException extends RuntimeException { public AesDecodeException() { } public AesDecodeException(String message) { super(message); } public AesDecodeException(String message, Throwable cause) { super(message, cause); } public AesDecodeException(Throwable cause) { super(cause); } public AesDecodeException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { super(message, cause, enableSuppression, writableStackTrace); } } /** * AES加密异常 */ public static class AesEncodeException extends RuntimeException { public AesEncodeException() { } public AesEncodeException(String message) { super(message); } public AesEncodeException(String message, Throwable cause) { super(message, cause); } public AesEncodeException(Throwable cause) { super(cause); } public AesEncodeException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { super(message, cause, enableSuppression, writableStackTrace); } } }