16位或32位密钥的AES-128 + BASE64加密算法 java实现
·
此次算法支持16位密钥和32位密钥加密,如果密钥长度是32位,则需要更新加密包,16位密钥则不需要更新加密包,不清楚怎样更新加密包的,可以查看加密专栏另一篇文章,在此不再赘述
如果只需要看AES128加密则只需要下面这个方法就可以了
/**
* AES128加密
* @param src 加密原串
* @param key 密钥
* @return
*/
public static String aesEncrypt(String src, String key) {
try{
if (key == null || key.equals("")) {
logger.info("密钥为空:"+ key);
return null;
}
byte[] raw = key.getBytes("utf-8");
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");//"算法/模式/补码方式"
cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
byte[] encrypted = cipher.doFinal(src.getBytes("utf-8"));
return Base64Coder.encodeLines(encrypted);//此处使用BASE64做转码功能,同时能起到2次加密的作用。
// 若有换行符困扰则使用:
// return Base64Coder.encodeLines(encrypted).replaceAll("[\\s*\t\n\r]", "");
}catch(Exception e){
e.printStackTrace();
return null;
}
}
实际开发可能会遇到的加密完整需求:去除某些属性、字典排序、构造加密原串、最后才是AES128加密等
/*
* aes128加密串获得
* @param param 待加密参数
* */
public static String aesSign(Map<String,String> param) {
// 实名认证密钥
String secretkey = PropertiesUtil.getProperty(GmsConstant.ADULT_AUTHENTICATION_SECRETKEY);
// 加密串
String signature = "";
// 去除数组中的空值、签名参数、appkey(不需要的可以去除此步骤)
Map<String, String> encrypteMap = paraFilter(param);
// 按ascii码排序(不需要的可以去除此步骤)
List<Map.Entry<String, String>> infoIds = asciiSort(encrypteMap);
// 构造待加密原串
String produceStr = produceAesStr(infoIds);
try {
signature = aesEncrypt(produceStr,secretkey);
} catch (Exception e) {
e.printStackTrace();
logger.info("aesSign签名异常-param:"+ param.toString());
}
return signature;
}
去除加密参数中的某些属性,可自定义
/**
* 除去空值、 sign 的系统参数和除去请求体外的业务参数(去除哪些参数可以自定义)
* @param para 请求要素
* @return 除去空值、sign 的系统参数和除去请求体外的业务参数后的参数
*/
public static Map<String, String> paraFilter(Map<String, String> para) {
Map<String, String> result = new HashMap<String, String>();
if (para == null || para.size() <= 0) {
return result;
}
for (String key : para.keySet()) {
String value = para.get(key);
if (value == null || value.equals("") || key.equalsIgnoreCase("data")
|| key.equalsIgnoreCase("sign")) {
continue;
}
result.put(key, value);
}
return result;
}
待加密参数按字典顺序排序
/**
* map集合按ascii码从小到大排序
* @param map 排序前的map集合
* @return List<Map.Entry<String, String>> 排序后的list集合
*/
public static List<Map.Entry<String, String>> asciiSort(Map<String, String> map) {
List<Map.Entry<String, String>> infoIds = new ArrayList<Map.Entry<String, String>>();
try {
infoIds = new ArrayList<Map.Entry<String, String>>(map.entrySet());
// 对所有传入参数按照字段名的 ASCII 码从小到大排序(字典序)
Collections.sort(infoIds, new Comparator<Map.Entry<String, String>>() {
public int compare(Map.Entry<String, String> o1, Map.Entry<String, String> o2) {
return (o1.getKey()).toString().compareTo(o2.getKey());
}
});
}catch(Exception e){
logger.info("asciiSort(参数异常):"+map);
e.printStackTrace();
}
return infoIds;
}
加密原串构造
/**
* 【实名认证】构造AES-128签名原串
* @param paramList 参数list
* @return "key":"val","key":"val"字符串(格式可以自定义)
*/
public static String produceAesStr(List<Map.Entry<String, String>> paramList) {
String result = "";
// 构造签名键值对的格式
StringBuilder sb = new StringBuilder();
sb.append("{");
for (Map.Entry<String, String> item : paramList) {
if (item.getKey() != null || item.getKey() != "") {
String key = item.getKey();
String val = item.getValue();
if (!(val == "" || val == null)) {
sb.append('"'+key + '"' + ':' + '"' + val + '"' + ",");
}
}
}
result = sb.toString();
// 去除末尾的","
if(result.length()>1){
return result.substring(0, sb.toString().length()-1)+"}";
}else {
return result;
}
}

更多推荐
所有评论(0)