天天看點

AES加密算法概述(前端登入加密)

AES簡介

進階加密标準(AES,Advanced Encryption Standard)為最常見的對稱加密算法(微信小程式加密傳輸就是用這個加密算法的)。對稱加密算法也就是加密和解密用相同的密鑰,具體的加密流程如下圖:

AES加密算法概述(前端登入加密)

下面簡單介紹下各個部分的作用與意義:

  • 明文P
沒有經過加密的資料。
           
  • 密鑰K
用來加密明文的密碼,在對稱加密算法中,加密與解密的密鑰是相同的。密鑰為接收方與發送方協商産生,但不可以直接在網絡上傳輸,
 否則會導緻密鑰洩漏,通常是通過非對稱加密算法加密密鑰,然後再通過網絡傳輸給對方,或者直接面對面商量密鑰。
 密鑰是絕對不可以洩漏的,否則會被攻擊者還原密文,竊取機密資料。
           
  • AES加密函數
設AES加密函數為E,則 C = E(K, P),其中P為明文,K為密鑰,C為密文。也就是說,
 把明文P和密鑰K作為加密函數的參數輸入,則加密函數E會輸出密文C。
           
  • 密文C
經加密函數處理後的資料
           
  • AES解密函數
設AES解密函數為D,則 P = D(K, C),其中C為密文,K為密鑰,P為明文。也就是說,
把密文C和密鑰K作為解密函數的參數輸入,則解密函數會輸出明文P。
           

簡單介紹下對稱加密算法與非對稱加密算法的差別。

  • 對稱加密算法
加密和解密用到的密鑰是相同的,這種加密方式加密速度非常快,
 适合經常發送資料的場合。缺點是密鑰的傳輸比較麻煩。
           
  • 非對稱加密算法
加密和解密用的密鑰是不同的,這種加密方式是用數學上的難解問題構造的,通常加密解密的速度比較慢,
适合偶爾發送資料的場合。優點是密鑰傳輸友善。常見的非對稱加密算法為RSA、ECC和EIGamal。
           

實際中,一般是通過RSA加密AES的密鑰,傳輸到接收方,接收方解密得到AES密鑰,然後發送方和接收方用AES密鑰來通信。

想了解更多點選AES加密算法的詳細實作與介紹

前端crypto-js加密

要用 AES 算法加密,首先我們要引入 crypto-js ,crypto-js 是一個純 javascript 寫的加密算法類庫 ,可以非常友善地在 javascript 進行 MD5、SHA1、SHA2、SHA3、RIPEMD-160 哈希散列,進行 AES、DES、Rabbit、RC4、Triple DES 加解密,我們可以采用 npm install crypto-js --save 進行下載下傳安裝,也可以直接去 GitHub下載下傳源碼~

項目中具體的步驟如下

1、 在package.json裡面添加"crypto-js": “^^3.1.9-1”

2、npm install 下載下傳crypto-js

3、引入 import CryptoJS from ‘crypto-js’

4、需要定義兩個方法 ,分别是用于加密和解密,這裡我将它放在了 utils 檔案夾下

const CryptoJS = require('crypto-js');  //引用AES源碼js
    
    const key = CryptoJS.enc.Utf8.parse("1234123412ABCDEF");  //十六位十六進制數作為密鑰
    const iv = CryptoJS.enc.Utf8.parse('ABCDEF1234123412');   //十六位十六進制數作為密鑰偏移量
    
    //解密方法
    function Decrypt(word) {
        let encryptedHexStr = CryptoJS.enc.Hex.parse(word);
        let srcs = CryptoJS.enc.Base64.stringify(encryptedHexStr);
        let decrypt = CryptoJS.AES.decrypt(srcs, key, { iv: iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 });
        let decryptedStr = decrypt.toString(CryptoJS.enc.Utf8);
        return decryptedStr.toString();
    }
    
    //加密方法
    function Encrypt(word) {
        let srcs = CryptoJS.enc.Utf8.parse(word);
        let encrypted = CryptoJS.AES.encrypt(srcs, key, { iv: iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 });
        return encrypted.ciphertext.toString().toUpperCase();
    }
    
    export default {
        Decrypt ,
        Encrypt
    }
           

上面的代碼中的 key 是密鑰 ,iv 是密鑰偏移量,這個一般是接口傳回的,為了友善,我們這裡就直接在這裡定義了。

值得注意的是密鑰的長度,由于對稱解密使用的算法是 AES-128-CBC算法,資料采用 PKCS#7 填充 , 是以這裡的 key 需要為16位!

接着我們定義了 解密方法Decrypt 和 加密方法 Encrypt ,最後通過 export default 将其暴露出去

示例

這裡我定義了一個 index.vue 用來展示資料加解密的操作~

加密操作: 假設我們現在要給後端發送一段文字,暫且定義為 This is a clear text , 在發送之前我們需要對其進行加密操作,這時候我們可以調用上面介紹的 Encrypt 方法,通過加密後我們可以得到密文為:4ACEA01505ADAF9FB59A03B22FC1EF1B244AE28DDACFDFAEFA7E263655C44357

AES加密算法概述(前端登入加密)

解密操作: 假設我們請求後端接口,後端傳回了我們一堆如下的字元串 BBFE62335C28821AD2F4043B715BB0C3E45734908254666526DCFD86A605F3AF , 這讓我很蒙蔽啊,這時候就要調用 Decrypt 方法,

通過解密我們可以拿到後端傳回的資訊其實是:{“name”:“Chris”,“sex”:“male”}

AES加密算法概述(前端登入加密)

代碼參考github

繼續閱讀