天天看點

前端加解密方案探讨

最近在做一個node項目,需要對前端傳遞給node端的敏感資料進行加密,并在node端對該加密資料進行解密;因為在做node項目之前,與後端配合開發過類似的需求,即前端加密後端解密;是以就嘗試采用RSA非對稱加密算法來實作。由于第一次采用RSA來完成加解密的整個過程,遇到了不少坑;不過由于種種原因,最後采用了AES的加密方式;下面就來說說前端加解密實作方案。

當然首先想到采用的加解密算法就是<code>RSA</code>,其關鍵在于算法的<code>公鑰/秘鑰</code>。其主要用法:

算法生成一份公鑰和私鑰,其中公鑰是公開的,所有人都可以知道,私鑰是保密的

用公鑰解密,要用私鑰解密

于是,基于RSA算法來實作加解密,找到了對應的浏覽器端庫<code>jsencrypt</code>和node端的庫<code>node-rsa</code>來實作具體的功能。

具體實作思路:

使用jsencrypt在前端實作用公玥加密,使用node-rsa在node端用私鑰解密。

由于采用的是RSA算法,是以需要前後端約定具體的公鑰和私鑰。怎麼生存公鑰私鑰呢?

于是根據<code>jsencrypt</code>庫的介紹,使用<code>openssl</code>方式來生成對應的公鑰和私鑰。于是生成的公鑰和私鑰大概是如下樣子:

于是,使用生成的公鑰,前端使用<code>jsencrypt</code>提供的加密api來對敏感資料加密

node端使用<code>node-rsa</code>來完成解密:

執行到這裡,node-rsa一直報下面的錯誤:

Error: Error during decryption (probably incorrect key). Original error: Error: Incorrect data or key

意思就是對應的解密私鑰不正确,檢視<code>node-rsa</code>有關公鑰私鑰,他是有規定的,具體如下:

前端加解密方案探讨

可以看出,node-rsa的公鑰私鑰的起始字元串有以下兩種:

pkcs1: 公鑰(-----BEGIN RSA PUBLIC KEY-----)和私鑰(-----BEGIN RSA PRIVATE KEY-----)

pkcs8: 公鑰(-----BEGIN PUBLIC KEY-----) 和 私鑰 (-----BEGIN PRIVATE KEY-----)

不管node-rsa規定的那種私鑰scheme,都與我們之前使用<code>openssl</code>生成的私鑰字元串的開始結束字元不同,導緻node-rsa認不出對應的私鑰。

那麼,我們是否可以對openssl生成的私鑰的起始字元串按照node-rsa進行修改呢,我們簡單試一下,結果産生如下錯誤:

InvalidAsn1Error: Expected 0x30: got 0x2

是以,既然不能按照openssl生成的公鑰私鑰方式,那麼能否有其他方式來生成呢?通過google發現,可以通過<code>node-rsa</code>的相關api來生成對應的公鑰私鑰,并且<code>jsencrypt</code>庫也可以通過其生成的公鑰來解密。node-rsa對應生成公鑰私鑰如下:

這樣,通過生成的公鑰,前端使用jsencrypt庫來加密,node端使用node-rsa根據私鑰來解密,解決了之前遇到問題。

在使用RSA加密算法前,使用過前端加密庫<code>crypto-js</code>來完成加解密,因為:

它算是比較成熟且github star數也比較多,使用起來比較放心。

crypto-js也提供了多種加密算法,唯獨不包含RSA加密算法。

該庫是前後端通用的庫,避免引入多個庫

基于此原因,選用了crypto-js提供的AES加密算法來完成需求。

具體的實作方式如下

具體代碼如下:

對應的node端代碼如下:

至此,前後端加解密就大功告成了。

上面兩種方式都能實作前後端的加密解密,就其安全性而言存在差别,具體可以參考如下對比表格:

加密算法

實作方式

安全性

RSA

前後端約定統一的公鑰私鑰,前端用暴露的公鑰加密,私鑰存在後server端

私鑰存在server端,即使暴露公鑰;加密是安全的

AES

前端後端都使用同樣的key(或者還有iv)來進行加解密,key同時暴露在前後端

由于後端使用同樣的key來解密,由于前端暴露了key,加密不安全

對于AES這種将加密key暴露在前端,不夠安全;但是前端加密是防不了小人的,如果真要防,可以将加密算法的js檔案進行壓縮加密,不斷更新的手段來使js檔案難以擷取,讓攻擊者難以擷取加密算法來防止。

1、jsencrypt

2、PHP 和 Web 端對稱加密傳輸|JSEncrypt|CryptoJS

3、node-rsa非對稱加密

4、js 前端 AES 及 RSA 加解密

下一篇: 死鎖