天天看點

加密函數庫(cryptojs庫)

(一)前言

當我們需要進行傳輸加密時候,正常需要使用一個加密庫,進行封裝,比如md5,base64,AES等等。這裡我介紹AES加密使用, AES加密算法的詳細介紹與實作

node.js 裡面的crypto-js其實包含了ase加密,但是在web端,可能你需要一個類庫

CryptoJS庫

crypto-js 是一個純 javascript 寫的加密算法類庫 ,可以非常友善地在 javascript 進行 MD5、SHA1、SHA2、SHA3、RIPEMD-160 哈希散列,進行 AES、DES、Rabbit、RC4、Triple DES 加解密

(二)sign簽名實作

首先我們來介紹下微信的sign簽名方式

// 首先需要一個對象
const APP_KEY = '233111111';
const APP_SECRET = '1231111111111111';

const letterList = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'.split('');

function getRandomInt(max) {
  return Math.floor(Math.random() * Math.floor(max));
}

function getRandom(num = 11) {
  return Array.from(Array(num)).map(() => letterList[getRandomInt(61)]).join('');
}

const map = {
    appKey: APP_KEY, // 這是key
    nonce_str: getRandom(11), // 擷取11位随機數
    timestamp: parseInt(String(+new Date() / 1000), 10), // 目前秒級時間戳
  };
// 然後根據這個對象,生成字元串  APP_SECRET 是密鑰
const stringSignTemp = `${Object.keys(result).map(key => `${key}=${result[key]}`).join('&')}&key=${APP_SECRET}`,

// 然後把這個生成的字元串,通過HmacSHA256生成秘文,然後轉為大寫字母
import CryptoJS from 'crypto-js';
const sign = CryptoJS.HmacSHA256(stringSignTemp, APP_SIGN_SECRET_KEY).toString().toUpperCase();
           

然後将得到sign通過請求頭帶給背景處理,這種傳輸因為基于微信,是以大部分情況下,隻要知道APP_KEY和APP_SECRET就很容易僞造簽名

(三)ase簽名實作

ase上面也說過了

// 首先需要一個對象(這裡和sign差不多)
const APP_KEY = '233111111';
const APP_SECRET = '1231111111111111';

const letterList = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'.split('');

function getRandomInt(max) {
  return Math.floor(Math.random() * Math.floor(max));
}

function getRandom(num = 11) {
  return Array.from(Array(num)).map(() => letterList[getRandomInt(61)]).join('');
}

const map = {
    appKey: APP_KEY, // 這是key
    nonce_str: getRandom(11), // 擷取11位随機數
    timestamp: parseInt(String(+new Date() / 1000), 10), // 目前秒級時間戳
  };

// 然後根據這個對象,生成字元串  APP_SECRET 是密鑰
const stringDataTemp = JSON.stringify(result)

// 然後把這個生成的字元串,通過AES生成秘文
const APP_DATA_SECRET_KEY = CryptoJS.enc.Utf8.parse(APP_KEY);
const APP_SIGN_SECRET_KEY = CryptoJS.enc.Utf8.parse(APP_SECRET);

function encodeData(stringDataTemp, iv) {
  const aesRes = CryptoJS.AES.encrypt(stringDataTemp, APP_DATA_SECRET_KEY, {
    iv: CryptoJS.enc.Utf8.parse(iv),  // iv是16位随機數
    mode: CryptoJS.mode.CBC,
    padding: CryptoJS.pad.Pkcs7,
  });
  return aesRes.toString();
}

// 當然我們也需要一個解密函數
function decodeData(word, iv) {
  const decrypt = CryptoJS.AES.decrypt(word, APP_DATA_SECRET_KEY, {
    iv: CryptoJS.enc.Utf8.parse(iv),
    mode: CryptoJS.mode.CBC,
    padding: CryptoJS.pad.Pkcs7,
  });
  const decryptedStr = decrypt.toString(CryptoJS.enc.Utf8);
  return decryptedStr.toString();
}
           

其實在加密和解密這塊,如果需要做的複雜,也可以多加密幾次,或者做一些其他處理。不過,實際上的加密就這麼多,如果要研究原理,建議還是看下庫本身的實作