当前位置:   article > 正文

对称加解密算法AES+加解密模式CBC+填充模式PKCS5_aes pkcs5

aes pkcs5

目录

参考文本

前言

AES简介

前端代码

后台代码

后台加密解密工具类代码

后台接收参数接口代码


参考文本

前端参考:

https://blog.csdn.net/z834410038/article/details/70231668

后端参考:

https://blog.csdn.net/aigoV/article/details/90374838

https://blog.csdn.net/huangxiaoguo1/article/details/78043169

前言

前段时间项目经常被攻击,有一种是请求被抓包并且修改了请求参数,为了解决这种问题,决定对请求参数进行加密,加密采用AES的CBC模式。对于加密之前没大接触过,AES的CBC模式是什么鬼?赶紧百度。下面是对AES加密的一点理解,直接复制来的。

AES简介

1、AES(Advanced Encryption Standard 高级加密标准)算法:

这是一种对称加密算法,强迫症一定要知道清楚啥对称加密,对称加密的意思是指,加密者和解密者用的是同一串秘钥。

2、128位加解密

这是在约定秘钥的长度,128位即128bit,AES的秘钥长度一般有:128bit、192bit、256bit。java 中,秘钥里的一个字符是一个字节(1byte),1byte=8bit。一个128位的秘钥,即由16个字符组成,如:"aigov1266aba186k".

3、加解密模式CBC

AES有四种加解密模式:CBC、EBC、CFB、OFB ,我这次被要求用CBC模式,所以大概了解一下CBC。其他几个,咱也不懂,咱也不敢说。CBC模式下,加密时,是对明文进行分组加密的,每组大小一致,到最后一组时,可能长度不够,这个时候就需要填充到一样长度,就有了下面的填充模式。

4、填充模式

有两种填充模式:PKCS5Padding、PKCS7Padding 。这两种填充模式填充规则一样,区别在于,分组时,每组约定大小不一样。PKCS5Padding要求块(block)的大小是8位,PKCS7Padding则没有明确,范围在1-255之间。

5、Base64编码

Base64编码就是将数据编码成只用大小写字母,0-9数字,以及符号 + /等64个字符的String字符串,一般我们在网络中传输较长的数据时,会选中这种编码方式。

明文在经过加密后后变成一个无规则的二进制(二进制文件)byte数组,如:

 ajax无法接收二进制流文件,此时为了展示和传输,我们一般会约定使用Base64编码进行编码。将二进制byte数组进行base64编码后,就得到如下形式字符串:

项目采用的是将流转换为16进制的String字符串进行传递,直接贴代码

前端代码

前端引入crypto-js.js和aes.js

crypto-js.js下载链接:https://gitee.com/zhangfanhao/CSDN/blob/master/crypto-js.js

aes.js下载链接:https://gitee.com/zhangfanhao/CSDN/blob/master/aes.js

  1. function supper() {
  2. var miyaokey = '后台代码加密解密类中main方法中将秘钥key转换为byte[],再转换为16进制的字符串的值';
  3. miyaokey = CryptoJS.enc.Hex.parse(miyaokey)
  4. iv = CryptoJS.enc.Hex.parse("后台代码加密解密类中main方法中将iv转换为byte[],再转换为16进制的字符串的值");
  5. var src = JSON.stringify({
  6. "accessToken": "",
  7. "obj": {
  8. "keyWord":$(".commodity-seek-inp").val(),
  9. "sortType": "2",//排序方式按佣金高低倒序
  10. "withCoupon": "true",//只查有优惠劵的
  11. "isBrandGoods": "false",//只查品牌商品
  12. "optId":""//商品的分类Id
  13. },
  14. "page": page,
  15. "pageSize": "",
  16. "msg": ""
  17. });
  18. var enc = CryptoJS.AES.encrypt(src, miyaokey, {
  19. iv: iv,
  20. mode: CryptoJS.mode.CBC,
  21. padding: CryptoJS.pad.Pkcs7
  22. })
  23. enced = enc.ciphertext.toString();
  24. $.ajax({
  25. type: "POST",
  26. url: "请求地址",
  27. dataType: "json", //表示返回值类型,不必须
  28. data: enced,
  29. success: function(res) {
  30. },
  31. });
  32. }

后台代码

后台加密解密工具类代码

  1. import java.io.UnsupportedEncodingException;
  2. import java.nio.charset.Charset;
  3. import java.security.InvalidAlgorithmParameterException;
  4. import java.security.InvalidKeyException;
  5. import java.security.NoSuchAlgorithmException;
  6. import javax.crypto.BadPaddingException;
  7. import javax.crypto.Cipher;
  8. import javax.crypto.IllegalBlockSizeException;
  9. import javax.crypto.KeyGenerator;
  10. import javax.crypto.NoSuchPaddingException;
  11. import javax.crypto.SecretKey;
  12. import javax.crypto.spec.IvParameterSpec;
  13. import javax.crypto.spec.SecretKeySpec;
  14. public class AES {
  15. private static String iv = "0123456789ABCDEF";//当模式是CBC的时候必须设置偏移量,偏移量字符串:自己随意定义,必须是16位 。
  16. private static String Algorithm = "AES";
  17. private static String AlgorithmProvider = "AES/CBC/PKCS5Padding"; //算法/模式/补码方式
  18. private static String jiaMiKey = "1234567890ABCDEF1234567890ABCDEf"; //加密解密的秘钥key:自己随意定义。长度为n/8。 n代表的是多少bit
  19. public static IvParameterSpec getIv() throws UnsupportedEncodingException {
  20. IvParameterSpec ivParameterSpec = new IvParameterSpec(iv.getBytes("utf-8"));
  21. return ivParameterSpec;
  22. }
  23. public static byte[] encrypt(String src, byte[] key) throws NoSuchAlgorithmException, NoSuchPaddingException,
  24. InvalidKeyException, IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException, InvalidAlgorithmParameterException {
  25. SecretKey secretKey = new SecretKeySpec(key, Algorithm);
  26. IvParameterSpec ivParameterSpec = getIv();
  27. Cipher cipher = Cipher.getInstance(AlgorithmProvider);
  28. cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivParameterSpec);
  29. byte[] cipherBytes = cipher.doFinal(src.getBytes(Charset.forName("utf-8")));
  30. return cipherBytes;
  31. }
  32. public static byte[] decrypt(String src, byte[] key) throws Exception {
  33. SecretKey secretKey = new SecretKeySpec(key, Algorithm);
  34. IvParameterSpec ivParameterSpec = getIv();
  35. Cipher cipher = Cipher.getInstance(AlgorithmProvider);
  36. cipher.init(Cipher.DECRYPT_MODE, secretKey, ivParameterSpec);
  37. byte[] hexBytes = hexStringToBytes(src);
  38. byte[] plainBytes = cipher.doFinal(hexBytes);
  39. return plainBytes;
  40. }
  41. public static String toKeyCode(String src) {
  42. byte key[] = new byte[0];
  43. String to = null;
  44. try {
  45. key = jiaMiKey.getBytes("utf-8");
  46. to = new String(decrypt(src, key), "utf-8");
  47. } catch (Exception e) {
  48. e.printStackTrace();
  49. }
  50. return to;
  51. }
  52. public static String deKeyCode(String src) {
  53. byte key[] = new byte[0];
  54. String to = null;
  55. try {
  56. key = jiaMiKey.getBytes("utf-8");
  57. to = byteToHexString(encrypt(src, key));
  58. } catch (Exception e) {
  59. e.printStackTrace();
  60. }
  61. return to;
  62. }
  63. /**
  64. * 将byte转换为16进制字符串
  65. * @param src
  66. * @return
  67. */
  68. public static String byteToHexString(byte[] src) {
  69. StringBuilder sb = new StringBuilder();
  70. for (int i = 0; i < src.length; i++) {
  71. int v = src[i] & 0xff;
  72. String hv = Integer.toHexString(v);
  73. if (hv.length() < 2) {
  74. sb.append("0");
  75. }
  76. sb.append(hv);
  77. }
  78. return sb.toString();
  79. }
  80. /**
  81. * 将16进制字符串装换为byte数组
  82. * @param hexString
  83. * @return
  84. */
  85. public static byte[] hexStringToBytes(String hexString) {
  86. hexString = hexString.toUpperCase();
  87. int length = hexString.length() / 2;
  88. char[] hexChars = hexString.toCharArray();
  89. byte[] b = new byte[length];
  90. for (int i = 0; i < length; i++) {
  91. int pos = i * 2;
  92. b[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
  93. }
  94. return b;
  95. }
  96. private static byte charToByte(char c) {
  97. return (byte) iv.indexOf(c);
  98. }
  99. public static void main(String[] args) {
  100. try {
  101. byte key[] = jiaMiKey.getBytes("utf-8");
  102. System.out.println(byteToHexString(key));//给前端的加密key
  103. } catch (UnsupportedEncodingException e) {
  104. e.printStackTrace();
  105. }
  106. try {
  107. byte[] vi = iv.getBytes("utf-8");
  108. System.out.println(byteToHexString(vi));//给前端的iv
  109. } catch (UnsupportedEncodingException e) {
  110. e.printStackTrace();
  111. }
  112. }
  113. }

后台接收参数接口代码

  1. @PostMapping("/searchGoods")
  2. public ResultObjVO searchDuoDuoJinBaoGoods(HttpServletRequest req) throws IOException {
  3. String param = AES.toKeyCode(IOUtils.toString(req.getInputStream(), "UTF-8"));//IOUtils.toString(req.getInputStream(), "UTF-8")返回的是前端传过来加密的参数。
  4. }

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家小花儿/article/detail/717438
推荐阅读
相关标签
  

闽ICP备14008679号