CryptoJS中AES实现前后端通用加解密技术


Posted in Javascript onDecember 18, 2018

在项目中如果要对前后端传输的数据双向加密, 比如避免使用明文传输用户名,密码等数据。 就需要对前后端数据用同种方法进行加密,方便解密。这里介绍使用 CryptoJS 实现 AES 加解密。

首先需要下载前台使用 CryptoJS 实现 AES 加解密的,所以要先下载组件,下载 CryptoJS-v3.1.2 版本之后,文件中包含components 和 rollups 两个文件夹,components 文件夹下是单个组件,rollups 文件夹下是汇总,引用 rollups 下的 aes.js 文件即可。

已解决解密数据时出现的异常: exception:javax.crypto.IllegalBlockSizeException: Input length must be multiple of 16 when decrypting with padded cipher

 这里提供 CryptoJS-v3.1.2 的 Github链接

 先上后台Java代码: 

package com.company.pms.pmsbase.utils;
 
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
 
import org.apache.commons.codec.binary.Base64;
 
public class AesUtil {
 
 public static void main(String args[]) throws Exception {
 
  String content = "明文 123 abc";
 
  //加密
  String encrypted = encrypt(content, KEY, IV);
  //解密
  String decrypted = decrypt(encrypted, KEY, IV);
 
  System.out.println("加密前:" + content);
 
  System.out.println("加密后:" + encrypted);
 
  System.out.println("解密后:" + decrypted);
 }
 
 private static String KEY = "abcdef0123456789"; // 长度必须是 16
 
 private static String IV = "abcdef0123456789"; // 长度必须是 16
 
 /**
  * 加密返回的数据转换成 String 类型
  * @param content 明文
  * @param key 秘钥
  * @param iv 初始化向量是16位长度的字符串
  * @return
  * @throws Exception
  */
 public static String encrypt(String content, String key, String iv) throws Exception {
  // 将返回的加密过的 byte[] 转换成Base64编码字符串 !!!!很关键
  return base64ToString(AES_CBC_Encrypt(content.getBytes(), key.getBytes(), iv.getBytes()));
 }
 
 /**
  * 将解密返回的数据转换成 String 类型
  * @param content Base64编码的密文
  * @param key 秘钥
  * @param iv 初始化向量是16位长度的字符串
  * @return
  * @throws Exception
  */
 public static String decrypt(String content, String key, String iv) throws Exception {
  // stringToBase64() 将 Base64编码的字符串转换成 byte[] !!!与base64ToString()配套使用
  return new String(AES_CBC_Decrypt(stringToBase64(content), key.getBytes(), iv.getBytes()));
 }
 
 private static byte[] AES_CBC_Encrypt(byte[] content, byte[] keyBytes, byte[] iv){
  try {
   SecretKeySpec key = new SecretKeySpec(keyBytes, "AES");
   Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
   cipher.init(Cipher.ENCRYPT_MODE,key, new IvParameterSpec(iv));
   byte[] result = cipher.doFinal(content);
   return result;
  } catch (Exception e) {
   System.out.println("exception:"+e.toString());
  }
  return null;
 }
 
 private static byte[] AES_CBC_Decrypt(byte[] content, byte[] keyBytes, byte[] iv){
  try {
   SecretKeySpec key = new SecretKeySpec(keyBytes, "AES");
   Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
   cipher.init(Cipher.DECRYPT_MODE,key, new IvParameterSpec(iv));
   byte[] result = cipher.doFinal(content);
   return result;
  } catch (Exception e) {
   System.out.println("exception:"+e.toString());
  }
  return null;
 }
 
 /**
  * 字符串装换成 Base64
  */
 
 public static byte[] stringToBase64(String key) throws Exception {
  return Base64.decodeBase64(key.getBytes());
 }
 
 /**
  * Base64装换成字符串
  */
 public static String base64ToString(byte[] key) throws Exception {
  return new Base64().encodeToString(key);
 }
 
}

再上前端代码(需引用 rollups 目录下的 aes.js ):

function encodeAesString(data,key,iv){
 var key = CryptoJS.enc.Utf8.parse(key); 
 var iv = CryptoJS.enc.Utf8.parse(iv); 
 var encrypted =CryptoJS.AES.encrypt(data,key,{
 iv:iv, 
 mode:CryptoJS.mode.CBC,
 padding:CryptoJS.pad.Pkcs7 
 });
 //返回的是base64格式的密文 
 return encrypted;
}
 
// encrypted 为是base64格式的密文
function decodeAesString(encrypted,key,iv){
 var key = CryptoJS.enc.Utf8.parse(key);
 var iv = CryptoJS.enc.Utf8.parse(iv);
 var decrypted =CryptoJS.AES.decrypt(encrypted,key,{
 iv:iv,
 mode:CryptoJS.mode.CBC,
 padding:CryptoJS.pad.Pkcs7
 });
 return decrypted.toString(CryptoJS.enc.Utf8);
}
 
// 测试加、解密
function testAES(){
 var data = "明文 123 abc"; // 明文 
 var key = 'abcdef0123456789'; // 密钥 长度16
 var iv = 'abcdef0123456789'; // 密钥 长度16
 
 console.log("加密前:" + data);
 
 // 测试加密
 var encrypted = encodeAesString(data,key,iv); // 密文
 console.log("加密后: " + encrypted);
 
 var decryptedStr = decodeAesString(encrypted,key,iv);
 console.log("解密后: " + decryptedStr);
}

贴上效果图:

CryptoJS中AES实现前后端通用加解密技术

CryptoJS中AES实现前后端通用加解密技术

中间遇到的问题: 

    1.  秘钥问题, 秘钥的长度必须为16位, 否则会报错

    2. 加密得到的 byte[] 需用使用Base64转换成字符串, 不能直接转成字符串,因为加密所采用的AES, MD5, SHA-256, SHA-512 等等算法,它们是通过对byte[] 进行各种变换和运算,得到加密之后的byte[],那么这个加密之后的 byte[] 结果显然 就不会符合任何一种的编码方案,比如 UTF-8, GBK等,因为加密的过程是任意对byte[]进行运算的。所以你用任何一种编码方案来解码 加密之后的 byte[] 结果,得到的都会是乱码。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
jQuery 性能优化指南(2)
May 21 Javascript
JQuery制作的放大效果的popup对话框(未添加任何jquery plugin)分享
Apr 28 Javascript
javascript事件委托的用法及其好处简析
Apr 04 Javascript
JavaScript每天必学之事件
Sep 18 Javascript
angular.js4使用 RxJS 处理多个 Http 请求
Sep 23 Javascript
浅谈webpack打包过程中因为图片的路径导致的问题
Feb 21 Javascript
Vue项目中使用Vux的安装过程
May 01 Javascript
Vue项目报错:Uncaught SyntaxError: Unexpected token
Nov 10 Javascript
vue轻量级框架无法获取到vue对象解决方法
May 12 Javascript
JS实现移动端点击按钮复制文本内容
Jul 28 Javascript
vue将后台数据时间戳转换成日期格式
Jul 31 Javascript
jQuery实现电梯导航模块
Dec 22 jQuery
antd组件Upload实现自己上传的实现示例
Dec 18 #Javascript
微信小程序解除10个请求并发限制
Dec 18 #Javascript
vue项目中axios请求网络接口封装的示例代码
Dec 18 #Javascript
vue中引入第三方字体文件的方法示例
Dec 17 #Javascript
vue 表单验证按钮事件交由父组件触发的方法
Dec 17 #Javascript
Vue 报错TypeError: this.$set is not a function 的解决方法
Dec 17 #Javascript
vuex 解决报错this.$store.commit is not a function的方法
Dec 17 #Javascript
You might like
linux下编译安装memcached服务
2014/08/03 PHP
PHPer 需要了解的 5 个 Composer 小技巧
2014/08/18 PHP
PHP文件读写操作相关函数总结
2014/11/18 PHP
PHP+MySQL统计该库中每个表的记录数并按递减顺序排列的方法
2016/02/15 PHP
php实现简易计算器
2020/08/28 PHP
jQuery使用手册之 事件处理
2007/03/24 Javascript
js利用与或运算符优先级实现if else条件判断表达式
2010/04/15 Javascript
JavaScript初学者应注意的七个细节详细介绍
2012/12/27 Javascript
js与jQuery 获取父窗、子窗的iframe
2013/12/20 Javascript
Javascript中常见的校验如域名、手机、邮箱等等
2014/01/02 Javascript
JavaScript动态加载样式表的方法
2015/03/21 Javascript
了解JavaScript表单操作和表单域
2019/05/27 Javascript
vue3实现v-model原理详解
2019/10/09 Javascript
js屏蔽F12审查元素,禁止修改页面代码等实现代码
2020/10/02 Javascript
[01:19:23]2018DOTA2亚洲邀请赛 4.5 淘汰赛 Mineski vs VG 第二场
2018/04/06 DOTA
[48:12]Secret vs Optic Supermajor 胜者组 BO3 第三场 6.4
2018/06/05 DOTA
[03:04]2018年度DOTA2玩家最喜爱的主播-完美盛典
2018/12/16 DOTA
在win和Linux系统中python命令行运行的不同
2016/07/03 Python
django model去掉unique_together报错的解决方案
2016/10/18 Python
遗传算法python版
2018/03/19 Python
对pytorch网络层结构的数组化详解
2018/12/08 Python
selenium+python截图不成功的解决方法
2019/01/30 Python
Python数据报表之Excel操作模块用法分析
2019/03/11 Python
Python Django 前后端分离 API的方法
2019/08/28 Python
Pycharm 2020最新永久激活码(附最新激活码和插件)
2020/09/17 Python
python单元测试框架pytest的使用示例
2020/10/07 Python
html5的canvas元素使用方法介绍(画矩形、画折线、圆形)
2014/04/14 HTML / CSS
2014第二批党员干部对照“四风”找差距检查材料思想汇报
2014/09/18 职场文书
公安派出所所长四风问题个人对照检查材料
2014/10/04 职场文书
委托培训协议书
2014/11/17 职场文书
二年级语文下册复习计划
2015/01/19 职场文书
表扬信格式模板
2015/05/05 职场文书
奥巴马开学演讲观后感
2015/06/12 职场文书
党员理论学习心得体会
2016/01/21 职场文书
七年级思品教学反思
2016/02/20 职场文书
SQL Server 忘记密码以及重新添加新账号
2022/04/26 SQL Server