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

 

感谢

 

posted @ 2019-11-26 10:44  习惯沉淀  阅读(1821)  评论(0编辑  收藏  举报