目前在前端開發中基本都會用到加密,最常見的就是登錄密碼的加密。接下來會為大家介紹幾種加密方法。
1. md5 加密
MD5 加密后的位數有兩種:16 位與 32 位。默認使用32位。 (16 位實際上是從 32 位字符串中取中間的第 9 位到第 24 位的部分)為提高安全性。根據業務需求,可以對md5 添加偏移量。如對原有字符拼接指定位數的字符串。
1.1 使用方法
npm install --save js-md5
// 然后在頁面中 引入
import md5 from 'js-md5';
md5('holle') // bcecb35d0a12baad472fbe0392bcc043
復制代碼
擴展
md5 支持算法
md5.hex(''); // d41d8cd98f00b204e9800998ecf8427e
md5.array(''); // [212, 29, 140, 217, 143, 0, 178, 4, 233, 128, 9, 152, 236, 248, 66, 126]
md5.digest(''); // [212, 29, 140, 217, 143, 0, 178, 4, 233, 128, 9, 152, 236, 248, 66, 126]
md5.arrayBuffer(''); // ArrayBuffer
md5.buffer(''); // ArrayBuffer, deprecated, This maybe confuse with Buffer in node.js. Please use arrayBuffer instead.
md5.base64('');
2. base64 加密
2.1 使用方法
npm install --save js-base64
// 引入
let Base64 = require('js-base64').Base64
// 加密
Base64.encode('測試'); // 5bCP6aO85by+
Base64.encodeURI('測試'); // 5bCP6aO85by-
// 解密
Base64.decode('5bCP6aO85by+'); // 測試
// note .decodeURI() is unnecessary since it accepts both flavors
Base64.decode('5bCP6aO85by-'); // 測試
3.res 加密
前端 js 庫:jsencrypt.js
背景:前端數據加密傳到后台,后台經過解密,進行數據處理。 在項目開發過程中,為了保證數據的安全性,在進行前端后端數據傳輸的過程中,需要對數據進行加密解密。
現在比較安全且流行的加密方式是非對稱加密(RSA)。其加密方式需要兩個秘鑰:私鑰(私有秘鑰)和公鑰(公開秘鑰)。公鑰加密,私鑰解密。
RSA 加密規則
公鑰(publicKey)加密、私鑰(privateKey)解密。不能逆向,私鑰(privateKey)加密、公鑰(publicKey)解密。說白了就是前后端都需要用公鑰(publicKey)進行加密,用私鑰(privateKey)進行解密。
為啥不可逆呢?前端代碼的安全性差,是總所周知的。之所以稱為私鑰(privateKey),就是因為是私密的,不可公開的,需要確保 key 的安全。若前端私鑰(privateKey)加密,就意味着需要將私鑰放到前端保存,這是不安全的,也違背了確保數據安全的初衷。
RSA 雙向加密解密
在開發過程中遇到這樣一個問題:前端不光要加密數據傳到后端,也需要將后端的傳回來的加密數據解密。所以定義了兩個方法,進行數據的加密解密。
引入前端 JS 庫:jsencrypt.js
// RSA 解密
static decryptRSA(str: string) {
const encryptor = new JSEncrypt() // 新建JSEncrypt對象
const privateKey = "XXXX" // 私鑰串
encryptor.setPrivateKey(privateKey)//設置私鑰
const decrytStr = encryptor.decrypt(str)
return decrytStr
}
// RSA 加密
static encryptRSA(str: string) {
const encryptor = new JSEncrypt() // 新建JSEncrypt對象
const publicKey = ''; //公鑰串
encryptor.setPublicKey(publicKey) // 設置公鑰
const rsaPassWord = encryptor.encrypt(str)
return rsaPassWord
}
相信大家已經發現問題了,我們將私鑰(privateKey)、公鑰(publicKey)全部都放到了前端代碼中,前端的安全性差,可以很輕松的拿到秘鑰對,RSA 加密解密也失去了價值。那該如何解決這個問題?
通過前后端的溝通,我們采用雙向加密解密,就是使用兩套秘鑰來解決這個問題。何為雙向加密?
后端定義兩對秘鑰:秘鑰對A、秘鑰對B。
秘鑰對 公鑰 私鑰
A publicKeyA privateKeyA
B publicKeyB privateKeyB
后端拿着:私鑰A(privateKeyA)、公鑰B(publicKeyB),前端拿着:公鑰A(publicKeyA)、私鑰B(privateKeyB)。
秘鑰對A -- 前端加密,后端解密
前端使用公鑰A(publicA)對數據進行加密,后端通過公鑰A(publicKeyA)對應的私鑰A(privateKeyA)進行解密。
秘鑰對B -- 前端解密,后端加密
后端使用公鑰B(publicKeyB)進行加密,前端通過公鑰B(publicKeyB)對應的私鑰A(privateKeyA)進行解密。
這樣就能保證,雖然私鑰(privateKeyB)和公鑰(publicKeyA)都在前端代碼中,但是這兩個並不是一對,就算是全部拿到,也無法成功解密。也符合公鑰(publicKey)加密、私鑰(privateKey)解密的規則。完美解決!
注意事項 這個插件對res加密的字符串最長是 117字符,
有時加密時,會遇到加密參數過長而無法加密的現象在源碼中加入以下代碼,通過調用encryptLong方法,重新定義加密函數即可。
JSEncrypt.prototype.encryptLong = function(string) {
var k = this.getKey();
// var maxLength = (((k.n.bitLength()+7)>>3)-11);
var maxLength = 117;
try {
var lt = "";
var ct = "";
if (string.length > maxLength) {
lt = string.match(/.{1,117}/g);
lt.forEach(function(entry) {
var t1 = k.encrypt(entry);
ct += t1 ;
});
return hex2b64(ct);
}
var t = k.encrypt(string);
var y = hex2b64(t);
return y;
}
catch (ex) {
return false;
}
};