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();
感谢
作者:习惯沉淀
如果文中有误或对本文有不同的见解,欢迎在评论区留言。
如果觉得文章对你有帮助,请点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
扫码关注一线码农的学习见闻与思考。
回复"大数据","微服务","架构师","面试总结",获取更多学习资源!