小工具知识网

当前位置: 首页 > 行业知识 > 前端使用 crypto-js 库 aes加解密

行业知识

前端使用 crypto-js 库 aes加解密

2026-11-02 17:46:14 来源:互联网转载

前端使用crypto-js AES 加密解密

CryptoJS���一个JavaScript加密算法库,用于在客户端浏览器中执行加密和解密操作。它提供了一系列常见的加密算法,如AES、DES、Triple DES、Rabbit、RC4、MD5、SHA-1等等。

()

AES

工作原理

AES(高级加密标准)是一种对称加密算法,即加密和解密使用相同的密钥。它可以加密长度为128、192和256位的数据块,并使用128位的密钥进行加密。AES算法使用了固定的块长度和密钥长度,并且被广泛应用于许多安全协议和标准中,例如SSL/TLS、SSH、IPSec等。

在AES加密中,明文被分成128位的块,每个块使用相同的密钥进行加密。加密过程包括以下步骤:

()
  • 密钥扩展:将密钥扩展为加密算法所需的轮密钥。

  • 初始轮:将明文分成块,并与第一轮密钥进行异或。

  • 多轮加密:将初始轮产生的结果反复进行多轮加密,每轮使用不同的轮密钥进行加密。

  • 最终轮:在最后一轮加密中,将块进行加密,但是不再进行下一轮加密,而是直接输出密文。

    解密过程与加密过程类似,只是将加密过程中的步骤反过来。需要注意的是,解密的过程中使用的是相同的密钥和轮密钥。由于AES是一种块加密算法,因此在加密过程中,需要对数据进行填充,确保数据块大小为128位。

    AES算法的优点
    • 安全性高:AES算法是一种可靠的加密算法,它在数据传输、文件加密和网络安全等领域有着广泛的应用。

    • 效率高:AES算法采用对称加密算法进行加密和解密,使用相同的密钥进行加密和解密。对称加密算法比非对称加密算法更加高效,因此AES算法具有更高的效率。

    • 应用广泛:AES算法在数据传输、文件加密和网络安全等领域有着广泛的应用。在数据传输过程中,AES算法可以对数据进行加密,保护数据的安全性。在文件加密过程中,AES算法可以对文件进行加密,保护文件的安全性。在网络安全领域,AES算法可以对网络数据进行加密,保护网络的安全性。

      github地址: https://github.com/brix/crypto-js

      cryptojs文档: https://cryptojs.gitbook.io/docs/#encoders

      在线aes加密解密工具: http://tool.chacuo.net/cryptaes

      安装

      script 标签嵌入

       

      npm 或 yarn 安装

      npm install crypto-jsyarn add crypto-js

      CommonJS

      const CryptoJS = require('crypto-js');

      ES module:

      import CryptoJS from 'crypto-js';
      封装加密和解密
      import CryptoJS from 'crypto-js' // ------------AES-------------  function getAesString(data, key, iv) { //加密   let keys = CryptoJS.enc.Utf8.parse(key)   let vis = CryptoJS.enc.Utf8.parse(iv)   let encrypt = CryptoJS.AES.encrypt(data, keys, {     iv: vis, //iv偏移量 CBC需加偏移量     mode: CryptoJS.mode.CBC, //CBC模式     // mode: CryptoJS.mode.ECB, //ECB模式     padding: CryptoJS.pad.Pkcs7 //padding处理   });   // debugger   return encrypt.toString(); //加密完成后,转换成字符串 }  function getDAesString(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); } // AES 对称秘钥加密 const aes = {   en: (data, key) => getAesString(data, key.key, key.iv),   de: (data, key) => getDAesString(data, key.key, key.iv) }; // BASE64 const base64 = {   en: (data) => CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse(data)),   de: (data) => CryptoJS.enc.Base64.parse(data).toString(CryptoJS.enc.Utf8) }; // SHA256 const sha256 = (data) => {   return CryptoJS.SHA256(data).toString(); }; // MD5 const md5 = (data) => { return CryptoJS.MD5(data).toString(); };  export { aes, md5, sha256, base64 }; 
      使用 JSEncrypt 生成密钥

      JSEncrypt是基于JavaScript的RSA加密库,允许在浏览器端使用RSA算法进行加密和解密操作。它提供了容易使用的API,简化了在客户端上进行加密的过程。

      JSEncrypt支持以下操作:

      • 生成密钥对: 可以使用JSEncrypt生成RSA密钥对,包括公钥和私钥。

      • 加密: 使用公钥加密数据,确保只有拥有私钥的服务器才能解密。

      • 解密: 使用私钥解密被公钥加密过的数据。

      • 密钥格式: JSEncrypt支持多种密钥格式,包括PEM格式(基于Base64编码)。

        使用JSEncrypt进行RSA加密的基本步骤如下:

        • 引入JSEncrypt库: 在HTML页面中引入JSEncrypt库的脚本文件。

        • 创建JSEncrypt对象: 使用JSEncrypt构造函数创建一个新的JSEncrypt对象。

        • 生成密钥对: 封装getKey()方法生成RSA密钥对,并将生成的私钥加密后传给后端。

        • 加密数据: 使用encrypt.encrypt(plainText)方法,将明文数据进行加密。

        • 解密数据: 在服务器端使用私钥进行解密,获取原始数据。

          需要注意的是,由于JSEncrypt是在客户端上执行的,所以密钥在传输过程中可能会存在安全风险。为了确保数据的安全性,建议在客户端和服务器之间使用安全的通信协议进行数据传输,并在服务器端进行进一步的安全验证和处理。

          import JSEncrypt from 'jsencrypt'const encrypt = new JSEncrypt();let publicKey = 'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCeCDcnFrS7DIRbvZLHreVUzaMbAFy2DYmioxBK606urY4rVR8IgLgUhnyw2/GQ99pyr8lGtqPeOoapantw1XwEVyi74MDxs4UDL8j4OZR1Es7HVGOB0GwKWobdU9cm/1iDwGyouSmijxKyAePg6KsLNgbjDPYZRS11bYEuZ8/RLQIDAQAB';encrypt.setPublicKey('-----BEGIN PUBLIC KEY-----' + publicKey + '-----END PUBLIC KEY-----')const random = (length) => {  var str = Math.random().toString(36).substr(2);  if (str.length>=length) {    return str.substr(0, length);  }  str += random(length-str.length);  return str;}export const rsaEncode = (src)=>{  let data = encrypt.encrypt(src); // 加密  return data};export const getKey = ()=>{  let key = { key: random(16), iv: random(16) }; // 生成密钥  let code = rsaEncode(key.key + ',' + key.iv) // 给密钥加密,在将加密后的密钥传给后端  window.codeArr = window.codeArr || {}  codeArr[code] = key  return {    key, code  }};export const getAesKey = (aes)=>{  let key = JSON.parse(JSON.stringify(codeArr[aes]))  delete codeArr[aes]  return key};window.getKey = getKeywindow.rsaEncode = rsaEncode

          publicKey 可以通过发请求后端返回,也可以自己定义,要求前后端一致

          封装 axios 拦截器进行加密解密
          /** * * http配置 * */// 引入axios以及element ui中的loading和message组件import { aes } from "@/util/encrypt.js";import { getKey, getAesKey } from "@/config/key.js";import axios from "axios";import store from "../store";import router from "../router/router";import { Loading, Message } from "element-ui";import { getSessStore, setSessStore } from "@/util/store";// 超时时间if (store.online) axios.defaults.timeout = 20000;else axios.defaults.timeout = 0;//跨域请求,允许保存cookieaxios.defaults.withCredentials = true;// 统一加解密const Unify = {  // 统一加密方法  en(data, key) {    // 1.aes加密    let aesStr = aes.en(JSON.stringify(data), key);    return aesStr;  },  // 统一解密  de(aesStr, key) {    // 1.aes解密    let dataStr = aes.de(aesStr, key);    // 3.转json对象    let data = JSON.parse(dataStr);    return data;  },};let loadinginstace;let cfg, msg;msg = "服务器君开小差了,请稍后再试";function ens(data) {  // debugger  let src = [...data];  src = JSON.stringify(src);  let dataJm = aes.en(src);  return dataJm;}function des(data) {  // debugger  let src = [...data];  let dataJm = aes.de(src);  dataJm = JSON.parse(dataJm);  return dataJm;}const cancelToken = axios.CancelTokenconst source = cancelToken.source()//HTTPrequest拦截axios.interceptors.request.use(  function (config) {    console.log(config.data, "加密前入参---");    config.cancelToken = source.token; // 全局添加cancelToken    loadinginstace = Loading.service({      fullscreen: true,    });    if (store.getters.token) {      let info = getSessStore("token");      // console.log("info", info);      config.headers["Authorization"] = "Bearer " + info; // 让每个请求携带token-- ['X-Token']为自定义key 请根据实际情况自行修改    }    const contenttype = config.headers.common["Accept"];    let types = contenttype.includes("application/json");    let key = getKey(); // 获取密钥    config.headers["aes"] = key.code; // 将 aes 的 code 设置到请求头,传给后端解密    config.headers["name"] = "send";    if (types) {      if (config.method == "post" || config.method == "put") {        if (config.data) {          config.headers["crypto"] = true;          config.headers["content-type"] = "application/json";          let data = {            body: config.data,          };          let dataJm = Unify.en(data, key.key); // 加密 post 请求参数          config.data = dataJm;        }      }    }    return config;  },  (error) => {    return Promise.reject(error);  });//HTTPresponse拦截axios.interceptors.response.use(  (response) => {    loadinginstace.close();    let res = response.data || {};    if (response.headers["date"]) {      store.commit("setServiceTime", response.headers.date);    }    if (res.crypto) {      try {        let key = getAesKey(response.headers.aes); /// 拿到公钥加密字符串        if (!key) {          message("获取密钥异常", "error");          return Promise.reject(res);        }        // debugger        res = Unify.de(res.body, key);        response.data = res;      } catch (err) {        message("系统异常:" + err.message, "error");        return Promise.reject(err);      }    }    // debugger    if (res.code === 1) {      message(res.msg, "error");      return Promise.reject(res);    }    console.log(response, "解密后response");    return response;  },  (error) => {    console.log("错误信息", error);    loadinginstace.close();    const res = error.response || {};    if (res.status === 478 || res.status === 403 || res.status === 401) {      let resMsg = res.data.msg ? res.data.msg : res.data.data      if (res.status === 403) {        message('服务授权失败,请联系管理添加权限!', "error");      } else {        message(resMsg, "error");      }      let flg = res.data.msg.includes('当前登录状态已失效')      if (res.status === 478 && flg) {        //token失效        source.cancel('登录信息已过期'); // 取消其他正在进行的请求        store.dispatch("FedLogOut").then(() => {          router.push("/login"); ///test        });      }    } else if (res.status === 400) {      message(res.data.error_description, "error");    } else if (res.status === 202) {      //三方未绑定      this.$router.push({        path: "/",      });    } else if (res.status === 503 || res.status === 504) {      //服务异常      message(res.data, "error");    } else if (      (res.status === 401 && res.statusText == "Unauthorized") ||      res.data.error == "invalid_token" ||      res.data.error == "unauthorized"    ) {      //token失效      store.dispatch("FedLogOut").then(() => {        router.push("/login"); ///test      });    } else {      message(res.data.message, "error");    }    return Promise.reject(error);  });export function message(text, type) {  let t = text ? text : "服务或网络异常!"  Message({    message: t,    type: type,    duration: 30 * 1000,    center: true,    showClose: true  });}export default axios;

          总结

          加密: 使用 JSEncrypt 生成私钥 key 并将密钥 key 加密得到 code, 使用 CryptoJS.AES.encrypt() 和 key 加密请求数据,将 加密后的 code 设置在请求头,后端获取加密后 code 进行解密得到私钥 key ,再对请求数据解密得到原始数据

          解密: 前端获取响应头的key,通过解密 JSEncrypt 解密得到私钥 key, 使用 CryptoJS.AES.decrypt() 方法对响应数据进行解密,得到原始数据

上一篇:橡皮树养护宝典,轻松实现繁茂绿意,让你的家居绿意盎然!

下一篇:服务器怎么装模子教程视频?