加密算法类库,进行 MD5SHA1SHA2SHA3RIPEMD-160 哈希散列,进行 AESDESRabbitRC4Triple DES 加解密

1. 了解加密解密

  1. 对称加密: 加密和解密使用相同的密钥

    加密和解密用到的密钥是相同的,这种加密方式加密速度非常快,适合经常发送数据的场合。缺点是密钥的传输比较麻烦

    密钥配送问题:直接在网络上传输,会导致密钥泄漏。①面对面协商各自存储,②使用非对称加密该密钥传输

    • DES (Data Encryption Standard )每次只能加密64bit的数据,目前已经可以在短时间内被破解,不建议使用。

    • 3DES (Triple Data Encryption Algorithm)3重DES,用3个不一样的密钥加密解密再加密,目前被一些银行机构使用,但处理速度不快,也有安全性问题。

    • AES 高级加密标准(AES,Advanced Encryption Standard) ,取代DES,通过了全世界密码学家所进行的高品质验证工作,小程序就使用的AES。

  2. 非对称加密: 加密和解密使用不同的密钥

    加密和解密用的密钥是不同的,这种加密方式是用数学上的难解问题构造的,通常加密解密的速度比较慢,适合偶尔发送数据的场合。优点是密钥传输方便

    RSA(由3位开发者的姓氏首字母组成)

  3. 注意

    实际中,一般是通过RSA加密AES的密钥,传输到接收方,接收方解密得到AES密钥,然后发送方和接收方用AES密钥来通信。

    模拟:

    ​ 1.假设在登录成功后,后端在返回体回传公钥。

    ​ 2.前端拿到公钥,自己定义一个对称密钥,用公钥对密钥进行加密传给后端。之后的敏感信息可用这个对称密钥加密。

    ​ 3.后端拿到对称密钥,使用私钥进行解密可以得到前端定义的对称密钥。使用这个对称密钥就可以解密前端之后传过来的敏感信息。

    AES对称加密理解图(参考):
    在这里插入图片描述
    RSA非对称加密理解图(参考):
    在这里插入图片描述

2. 实现库

前端可使用:

①crypto-js进行对称密钥的密文加密解密

②JS-RSA进行公钥+对称密钥进行加密,主要是得告诉后端对称密钥是啥:

后端(以nodejs为例)可使用:

①JS-RSA生成公钥密钥,把公钥传给前端

②crypto-js进行对称密钥的密文加密解密

链接:

3.方法封装-前端

非对称加密:可放入工具类文件夹:/src/utils/jsencrypt.js

import JSEncrypt from 'jsencrypt'
const pubKey = 'xxx' // 公钥 -- 后端拥有,是已生成的。
const priKey = 'xxx' // 秘钥 -- 后端拥有,是已生成的。
// RSA加密 --前端加密,该函数应该只发生一次调用,用于给后端传输对称密钥(参数data),参数pubKey为后端传来的公钥。
function rsaEncrypt(pubKey, data){
	const encrypt = new JSEncrypt()  // 创建加密对象实例
	encrypt.setPublicKey(pubKey) // 设置公钥
	return encrypt.encrypt(data) // 对内容加密 
}
// RSA解密 --后端解密,该函数也只可发生一次调用,用于解密前端传回的对称密钥加密。
function rsaDecrypt(data){
	const decrypt = new JSEncrypt()  // 创建加密对象实例
	decrypt.setPrivateKey(priKey) // 设置秘钥
	return decrypt.decrypt(data) // 对加密内容解密 
}
export default {
    rsaEncrypt,
    rsaDecrypt
}

对称加密解密:可放入工具类文件夹:/src/utils/secret.js

import CryptoJS from 'crypto-js'  //引用AES源码js  后端用const CryptoJS = require('crypto-j')

//十六位十六进制数作为密钥和密钥偏移量  前后端协定一致或前端进行定义通过非对称加密传给后端
const KEY = CryptoJS.enc.Utf8.parse("1234123412ABCDEF");  // 密钥 --前端写法
const IV = CryptoJS.enc.Utf8.parse('ABCDEF1234123412'); // 偏移量 --前端写法

let KEY = '';
let IV = '';
// 后端在非对称解密函数rsaDecrypt解析出对称密钥时,调用该函数设置密钥和偏移量(前端不需要,因为前端是写死的)
function setKeyIv({keyStr, ivStr}) {
    KEY = keyStr
    IV = ivStr
}

/**
 * AES解密
 * @param{json} word 解密字段 
 * @param{string} keyStr 自定义密钥 
 * @param{string} ivStr 自定义偏移量
 * @return{string} 返回明文
 */
function Decrypt(word, {keyStr, ivStr}) {
    let key = KEY
    let iv = IV

    if (keyStr && ivStr) {
        key = CryptoJS.enc.Utf8.parse(keyStr)
        iv = CryptoJS.enc.Utf8.parse(ivStr)
    }
    
    let encryptedHexStr = CryptoJS.enc.Hex.parse(word);
    let srcs = CryptoJS.enc.Base64.stringify(encryptedHexStr);
    let decrypt = CryptoJS.AES.decrypt(srcs, key, { 
        iv, 
        mode: CryptoJS.mode.CBC, 
        padding: CryptoJS.pad.Pkcs7 // CryptoJS.pad.ZeroPadding
    });
    let decryptedStr = decrypt.toString(CryptoJS.enc.Utf8);
    return decryptedStr.toString();
}

/**
 * AES加密 
 * @param{json} word 加密字段 
 * @param{string} keyStr 自定义密钥 
 * @param{string} ivStr 自定义偏移量
 * @return{string} 返回密文
 */
function Encrypt(word, {keyStr, ivStr}) {
    let key = KEY
    let iv = IV

    if (keyStr && ivStr) {
        key = CryptoJS.enc.Utf8.parse(keyStr)
        iv = CryptoJS.enc.Utf8.parse(ivStr)
    }
    
    let srcs = CryptoJS.enc.Utf8.parse(word);
    let encrypted = CryptoJS.AES.encrypt(srcs, key, { 
        iv, 
        mode: CryptoJS.mode.CBC, 
        padding: CryptoJS.pad.Pkcs7 // CryptoJS.pad.ZeroPadding  常用PKCS5, PKCS7, NOPADDING
    });
    
    return CryptoJS.enc.Base64.stringify(encrypted.ciphertext) // 直接转base64
    // return encrypted.ciphertext.toString().toUpperCase(); // 加密后转大写
}

export default {
    Decrypt,
    Encrypt,
    setKeyIv
}

4. 示例

import secret from '引入secret.js路径'

const userInfo = {
  "name" : "admin",
  "pw" : "123456"
}

// 加密
const userInfoCrypto = secret.Encrypt(JSON.stringify(userInfo))
// 解密
secret.Decrypt(userInfoCrypto)

5. 不使用封装

var CryptoJS = require("crypto-js");
  
//加密 Utf8.parse -> Base64.stringify
var rawStr = "hello world!";
var wordArray = CryptoJS.enc.Utf8.parse(rawStr);
var base64Str = CryptoJS.enc.Base64.stringify(wordArray);
console.log('encrypted:', base64Str); // encrypted: aGVsbG8gd29ybGQh
  
//解密 Base64.parse -> toString
var parsedWordArray = CryptoJS.enc.Base64.parse(base64Str);
var parsedStr = parsedWordArray.toString(CryptoJS.enc.Utf8);
console.log("parsed:",parsedStr); // parsed: hello world!

//以上的功能仅仅是base64转换!!!

6. 说明

1. 在CryptoJS中,采用WordArray类型来传递数据,简单理解就是words是一个byte数组
2. WordArray的这个对象具有toString()方法,所以在js中是可以直接隐式转换成字符串的,**但是默认是Hex编码(16进制)**
3. 对称解密使用的算法是 `AES-128-CBC`算法,数据采用 `PKCS#7` 填充 , 因此这里的 `key` 需要为16位!

总结

文档下载链接:Lee敢敢资源下载链接跳转
get!!!

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐