zoukankan      html  css  js  c++  java
  • AES加密解密工具类(推荐使用CBC模式)

      AES加密算法,用于不能明文发送的报文中(比如个人信息中的身份证,手机等重要私密信息),后端加密,前端解密。

    import org.apache.commons.codec.binary.Base64;
    import org.apache.commons.lang3.RandomStringUtils;
    import org.apache.commons.lang3.StringUtils;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    import javax.crypto.Cipher;
    import javax.crypto.spec.IvParameterSpec;
    import javax.crypto.spec.SecretKeySpec;
    
    
    public class AESUtils {
        //日志相关
        private static final Logger log = LoggerFactory.getLogger(AESUtils.class);
        //编码
        private static final String ENCODING = "UTF-8";
        // 算法定义
        private static final String AES_ALGORITHM = "AES";
        // 指定填充方式
        private static final String CIPHER_PADDING = "AES/ECB/PKCS5Padding";
        private static final String CIPHER_CBC_PADDING = "AES/CBC/PKCS5Padding";
        //偏移量(CBC中使用,增强加密算法强度)
        private static final String IV_SEED = "1234567812345678";
    
        /**
         * AES加密
         * @param content 待加密内容
         * @param aesKey  密码
         * @return
         */
        public static String encrypt(String content, String aesKey){
            if(StringUtils.isBlank(content)){
                log.info("AES encrypt: the content is null!");
                return null;
            }
            //判断秘钥是否为16位
            if(StringUtils.isNotBlank(aesKey) && aesKey.length() == 16){
                try {
                    //对密码进行编码
                    byte[] bytes = aesKey.getBytes(ENCODING);
                    //设置加密算法,生成秘钥
                    SecretKeySpec skeySpec = new SecretKeySpec(bytes, AES_ALGORITHM);
                    // "算法/模式/补码方式"
                    Cipher cipher = Cipher.getInstance(CIPHER_PADDING);
                    //选择加密
                    cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
                    //根据待加密内容生成字节数组
                    byte[] encrypted = cipher.doFinal(content.getBytes(ENCODING));
                    //返回base64字符串
                    return Base64.encodeBase64String(encrypted);
                } catch (Exception e) {
                    log.info("AES encrypt exception:" + e.getMessage());
                    throw new RuntimeException(e);
                }
    
            }else {
                log.info("AES encrypt: the aesKey is null or error!");
                return null;
            }
        }
    
        /**
         * 解密
         * @param content 待解密内容
         * @param aesKey  密码
         * @return
         */
        public static String decrypt(String content, String aesKey){
            if(StringUtils.isBlank(content)){
                log.info("AES decrypt: the content is null!");
                return null;
            }
            //判断秘钥是否为16位
            if(StringUtils.isNotBlank(aesKey) && aesKey.length() == 16){
                try {
                    //对密码进行编码
                    byte[] bytes = aesKey.getBytes(ENCODING);
                    //设置解密算法,生成秘钥
                    SecretKeySpec skeySpec = new SecretKeySpec(bytes, AES_ALGORITHM);
                    // "算法/模式/补码方式"
                    Cipher cipher = Cipher.getInstance(CIPHER_PADDING);
                    //选择解密
                    cipher.init(Cipher.DECRYPT_MODE, skeySpec);
    
                    //先进行Base64解码
                    byte[] decodeBase64 = Base64.decodeBase64(content);
    
                    //根据待解密内容进行解密
                    byte[] decrypted = cipher.doFinal(decodeBase64);
                    //将字节数组转成字符串
                    return new String(decrypted, ENCODING);
                } catch (Exception e) {
                    log.info("AES decrypt exception:" + e.getMessage());
                    throw new RuntimeException(e);
                }
    
            }else {
                log.info("AES decrypt: the aesKey is null or error!");
                return null;
            }
        }
    
        /**
         * AES_CBC加密
         * @param content 待加密内容
         * @param aesKey  密码
         * @return
         */
        public static String encryptCBC(String content, String aesKey){
            if(StringUtils.isBlank(content)){
                log.info("AES_CBC encrypt: the content is null!");
                return null;
            }
            //判断秘钥是否为16位
            if(StringUtils.isNotBlank(aesKey) && aesKey.length() == 16){
                try {
                    //对密码进行编码
                    byte[] bytes = aesKey.getBytes(ENCODING);
                    //设置加密算法,生成秘钥
                    SecretKeySpec skeySpec = new SecretKeySpec(bytes, AES_ALGORITHM);
                    // "算法/模式/补码方式"
                    Cipher cipher = Cipher.getInstance(CIPHER_CBC_PADDING);
                    //偏移
                    IvParameterSpec iv = new IvParameterSpec(IV_SEED.getBytes(ENCODING));
                    //选择加密
                    cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
                    //根据待加密内容生成字节数组
                    byte[] encrypted = cipher.doFinal(content.getBytes(ENCODING));
                    //返回base64字符串
                    return Base64.encodeBase64String(encrypted);
                } catch (Exception e) {
                    log.info("AES_CBC encrypt exception:" + e.getMessage());
                    throw new RuntimeException(e);
                }
    
            }else {
                log.info("AES_CBC encrypt: the aesKey is null or error!");
                return null;
            }
        }
    
        /**
         * AES_CBC解密
         * @param content 待解密内容
         * @param aesKey  密码
         * @return
         */
        public static String decryptCBC(String content, String aesKey){
            if(StringUtils.isBlank(content)){
                log.info("AES_CBC decrypt: the content is null!");
                return null;
            }
            //判断秘钥是否为16位
            if(StringUtils.isNotBlank(aesKey) && aesKey.length() == 16){
                try {
                    //对密码进行编码
                    byte[] bytes = aesKey.getBytes(ENCODING);
                    //设置解密算法,生成秘钥
                    SecretKeySpec skeySpec = new SecretKeySpec(bytes, AES_ALGORITHM);
                    //偏移
                    IvParameterSpec iv = new IvParameterSpec(IV_SEED.getBytes(ENCODING));
                    // "算法/模式/补码方式"
                    Cipher cipher = Cipher.getInstance(CIPHER_CBC_PADDING);
                    //选择解密
                    cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
    
                    //先进行Base64解码
                    byte[] decodeBase64 = Base64.decodeBase64(content);
    
                    //根据待解密内容进行解密
                    byte[] decrypted = cipher.doFinal(decodeBase64);
                    //将字节数组转成字符串
                    return new String(decrypted, ENCODING);
                } catch (Exception e) {
                    log.info("AES_CBC decrypt exception:" + e.getMessage());
                    throw new RuntimeException(e);
                }
    
            }else {
                log.info("AES_CBC decrypt: the aesKey is null or error!");
                return null;
            }
        }
    
        public static void main(String[] args) {
            String random = RandomStringUtils.random(16, "abcdefghijklmnopqrstuvwxyz1234567890");
            System.out.println("随机:" + random);
            String aesResult = encrypt("测试AES加密12", random);
            System.out.println("aes加密结果:" + aesResult);
    
            System.out.println("---------解密---------");
            String decrypt = decrypt(aesResult, random);
            System.out.println("aes解密结果:" + decrypt);
    
    
            System.out.println("--------AES_CBC加密解密---------");
            String cbcResult = encryptCBC("测试AES加密12456", random);
            System.out.println("aes_cbc加密结果:" + cbcResult);
            System.out.println("---------解密CBC---------");
            String cbcDecrypt = decryptCBC(cbcResult, random);
            System.out.println("aes解密结果:" + cbcDecrypt);
        }
    }
  • 相关阅读:
    OLAP、OLTP的介绍和比较
    Python发行版本Anaconda的安装说明:基于Anaconda2-4.3.1-Windows-x86_64
    Hive学习:Hive连接JOIN用例详解
    Linux学习一:图解CentOS 6.5安装步骤
    Linux学习二:基于CentOS 6.5的网络配置
    一个恒等式.jpg
    centos 7 The path "" is not a valid path to the 3.10.0-229.el7.x86_64 kernel headers. Would you like to change it?
    Redis从入门到精通
    solr服务的搭建
    SpringMvc的运行流程
  • 原文地址:https://www.cnblogs.com/8593l/p/12575468.html
Copyright © 2011-2022 走看看