admin管理员组文章数量:1653245
目录
- 1. 了解加密解密
- 2. 实现库
- 3.方法封装-前端
- 4. 示例
- 5. 不使用封装
- 6. 说明
- 总结
加密算法类库,进行
MD5
、
SHA1
、
SHA2
、
SHA3
、
RIPEMD-160
哈希散列,进行
AES
、
DES
、
Rabbit
、
RC4
、
Triple DES
加解密
1. 了解加密解密
-
对称加密: 加密和解密使用相同的密钥
加密和解密用到的密钥是相同的,这种加密方式加密速度非常快,适合经常发送数据的场合。缺点是密钥的传输比较麻烦。
密钥配送问题:直接在网络上传输,会导致密钥泄漏。①面对面协商各自存储,②使用非对称加密该密钥传输。
-
DES (Data Encryption Standard )每次只能加密64bit的数据,目前已经可以在短时间内被破解,不建议使用。
-
3DES (Triple Data Encryption Algorithm)3重DES,用3个不一样的密钥加密解密再加密,目前被一些银行机构使用,但处理速度不快,也有安全性问题。
-
AES 高级加密标准(AES,Advanced Encryption Standard) ,取代DES,通过了全世界密码学家所进行的高品质验证工作,小程序就使用的AES。
-
-
非对称加密: 加密和解密使用不同的密钥
加密和解密用的密钥是不同的,这种加密方式是用数学上的难解问题构造的,通常加密解密的速度比较慢,适合偶尔发送数据的场合。优点是密钥传输方便。
RSA(由3位开发者的姓氏首字母组成)
-
注意
实际中,一般是通过RSA加密AES的密钥,传输到接收方,接收方解密得到AES密钥,然后发送方和接收方用AES密钥来通信。
模拟:
1.假设在登录成功后,后端在返回体回传公钥。
2.前端拿到公钥,自己定义一个对称密钥,用公钥对密钥进行加密传给后端。之后的敏感信息可用这个对称密钥加密。
3.后端拿到对称密钥,使用私钥进行解密可以得到前端定义的对称密钥。使用这个对称密钥就可以解密前端之后传过来的敏感信息。
AES对称加密理解图(参考):
RSA非对称加密理解图(参考):
2. 实现库
前端可使用:
①crypto-js进行对称密钥的密文加密解密
②JS-RSA进行公钥+对称密钥进行加密,主要是得告诉后端对称密钥是啥:
后端(以nodejs为例)可使用:
①JS-RSA生成公钥密钥,把公钥传给前端
②crypto-js进行对称密钥的密文加密解密
链接:
-
JS-RSA: 用于执行OpenSSL RSA加密、解密和密钥生成的Javascript库,https://github/travist/jsencrypt
-
MD5: 单向散列加密md5 js库,https://github/blueimp/JavaScript-MD5
-
crypto-js: 对称加密AES js库,https://github/brix/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!!!
版权声明:本文标题:前端加密解密 && crypto-js 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://m.elefans.com/xitong/1729640240a1208529.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论