前端常用的幾種加密方法

語言: CN / TW / HK

目前在前端開發中基本都會用到加密,最常見的就是登入密碼的加密。接下來會為大家介紹幾種加密方法。

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   github 地址: github.com/travist/jse…

背景:前端資料加密傳到後臺,後臺經過解密,進行資料處理。 在專案開發過程中,為了保證資料的安全性,在進行前端後端資料傳輸的過程中,需要對資料進行加密解密。

現在比較安全且流行的加密方式是非對稱加密(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;
      }
    };
複製程式碼

點贊支援、手留餘香、與有榮焉,動動你發財的小手喲,感謝各位大佬能留下您的足跡。

如果你覺得這篇文章對你有點用的話,麻煩請給我們的開源專案點點star: http://github.crmeb.net/u/defu不勝感激 !