zoukankan      html  css  js  c++  java
  • AES采用CBC模式128bit加密工具类

    写在前面

    安全测试ECB模式过于简单需要改为CBC模式加密以下为工具类及测试

    AESUtils.java

    package com.sgcc.mobile.utils;
    
    import sun.misc.BASE64Decoder;
    import sun.misc.BASE64Encoder;
    
    import javax.crypto.Cipher;
    import javax.crypto.spec.IvParameterSpec;
    import javax.crypto.spec.SecretKeySpec;
    import java.security.MessageDigest;
    import java.security.NoSuchAlgorithmException;
    import java.util.*;
    
    /**
     * AES加密128位CBC模式工具类
     */
    public class AESUtils {
    
        //算法/加密模式/填充方式
        private static final String ALGORITHMSTR = "AES/CBC/PKCS5Padding";//"算法/模式/补码方式"
    
        //解密密钥(自行随机生成)
        public static final String KEY = "qxhzngy266a186ke";//秘钥key
        public static final String IV = "1ci5crnda6ojzgtr";//偏移量iv
    
        //认证密钥(自行随机生成)
        public static final String AK = "s2ip9g3y3bjr5zz7ws6kjgx3ysr82zzw";//AccessKey
        public static final String SK = "uv8zr0uen7aim8m7umcuooqzdv8cbvtf";//SecretKey
    
        //加密
        public static String encrypt(String content) throws Exception {
            byte[] raw = KEY.getBytes("utf-8");
            SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
            Cipher cipher = Cipher.getInstance(ALGORITHMSTR);
            //使用CBC模式,需要一个向量iv,可增加加密算法的强度
            IvParameterSpec ips = new IvParameterSpec(IV.getBytes());
            cipher.init(Cipher.ENCRYPT_MODE, skeySpec, ips);
            byte[] encrypted = cipher.doFinal(content.getBytes());
            return new BASE64Encoder().encode(encrypted);
        }
    
        //解密
        public static StringBuffer decrypt(String content) throws Exception {
            try {
                byte[] raw = KEY.getBytes("utf-8");
                SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
                Cipher cipher = Cipher.getInstance(ALGORITHMSTR);
                IvParameterSpec ips = new IvParameterSpec(IV.getBytes());
                cipher.init(Cipher.DECRYPT_MODE, skeySpec, ips);
                byte[] encrypted1 = new BASE64Decoder().decodeBuffer(content);
                try {
                    byte[] original = cipher.doFinal(encrypted1);
                    StringBuffer originalString = new StringBuffer(new String(original));
                    return originalString;
                } catch (Exception e) {
                    System.out.println(e.toString());
                    return null;
                }
            } catch (Exception ex) {
                System.out.println(ex.toString());
                return null;
            }
        }
    
        //获取认证签名(身份认证需要)
        public static String getSign(String currentTime) throws Exception {
            String sign = "";
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("ak", AK);
            map.put("sk", SK);
            map.put("ts", currentTime);
            //获取 参数字典排序后字符串
            String decrypt = getOrderMap(map);
            try {
                //指定sha1算法
                MessageDigest digest = MessageDigest.getInstance("SHA-1");
                digest.update(decrypt.getBytes());
                //获取字节数组
                byte messageDigest[] = digest.digest();
                // Create Hex String
                StringBuffer hexString = new StringBuffer();
                // 字节数组转换为十六进制数
                for (int i = 0; i < messageDigest.length; i++) {
                    String shaHex = Integer.toHexString(messageDigest[i] & 0xFF);
                    if (shaHex.length() < 2) {
                        hexString.append(0);
                    }
                    hexString.append(shaHex);
                }
                sign = hexString.toString();
            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
            }
            return sign;
        }
    
        //获取参数的字典排序
        private static String getOrderMap(Map<String, Object> maps) {
            List<String> paramNames = new ArrayList<String>();
            for (Map.Entry<String, Object> entry : maps.entrySet()) {
                paramNames.add(entry.getValue().toString());
            }
            Collections.sort(paramNames);
            StringBuilder paramStr = new StringBuilder();
            for (String paramName : paramNames) {
                paramStr.append(paramName);
            }
            return paramStr.toString();
        }
    
    //    public static void main(String[] args) {
    //
    //        String mw = "123qwe!@#";
    //        StringBuffer stringBuffer = new StringBuffer();
    //
    //        try {
    //            String en = encrypt(mw);
    //            StringBuffer append = stringBuffer.append(en);
    //            System.out.println("加密" + append.toString());//w8RzmA/N1zPTRBKCYjoJgQ==
    //            StringBuffer decrypt = decrypt(append.toString());
    //            System.out.println("解密" + decrypt);//123qwe!@#
    //        } catch (Exception e) {
    //            e.printStackTrace();
    //        }
    //
    //    }
    
    }

    注意事项

    需要注意的是, 在获取解密后的内容后是由StringBuffer接收的, 解密内容使用完毕需要将StringBuffer清空, 不得不说也太安全了...

    StringBuffer清空方式有三种, 可参考如下方式:

    // 清空sb
    sb.setLength(0);//或sb.delete(0,sb.length());或sb = new StringBuffer();

    感谢

  • 相关阅读:
    管理软件数据库备份策略
    融云群组同步策略
    Nginx中配置undertow进行两个项目的动静分离配置
    记录mysql正在执行的SQL语句
    RabbitMQ启动出现的问题与解决办法
    延迟任务的实现总结
    查找所有sphinx引擎表并生成创建表的语句
    go 学习笔记(4) --变量与常量
    go 学习笔记(4) import
    go 学习笔记(4) package
  • 原文地址:https://www.cnblogs.com/yadongliang/p/11933891.html
Copyright © 2011-2022 走看看