<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
在網站專案中,有時我們需要對傳給後端的資料,比如 token 等進行加密處理。本文是對幾種常見的前端加密方法,以及如何使用開源的加密庫 crypto-js、JSEncrypt 來實現它們的分享。
又稱為訊息摘要演演算法,是不可逆的加密演演算法,即對明文進行加密後,無法通過得到的密文還原回去得到明文。一般所謂的比如 MD5 破解,其實是不斷的嘗試用不同的明文進行加密,直到得到的加密結果一致。
常見的單項雜湊函數有 MD5、SHA1、SHA256、SHA512 ,以及它們之前加上 Hmac(Keyed-hash message authentication codes) 後的 HmacMD5、HmacSHA1 等。下面以 MD5 為例重點介紹,其它幾種則可以舉一反三,不多贅述:
MD5 長度固定,不論輸入的內容有多少位元組,最終輸出結果都為 128 bit,即 16 位元組。這也就解釋了為什麼 MD5 以及其它單向雜湊函數是不可逆的 —— 輸出定長代表會有資料丟失。
通常,我們可以用 16 進位制字面值來表示它,每 4 bit 以 16 進位制字面值顯示,得到的是一個長度為 32 位的字串。注意,MD5 等單向雜湊函數具有高度的離散性,意思是隻要輸入的明文不一樣,得到的結果就完全不一樣,哪怕是僅僅多了一個空格。
MD5 有下面幾種使用場景:
為了方便,我採用了在普通 html 頁面直接引入 cdn 的方式來引入 crypto-js。
<script src="https://cdn.bootcdn.net/ajax/libs/crypto-js/4.1.1/crypto-js.min.js"></script>
引入後,我們就能得到 CryptoJS
這個物件,它包含了很多方法,列印結果如下圖:
其中就定義了 MD5
方法和 algo
物件,藉助它們,可以分別得到輸入資料的 MD5 結果:
CryptoJS.MD5('2022JueJin').toString()
結果為 84231025843afb62d818bf4f21612051。“2022JueJin” 就是我們需要加密的明文資料,得到的結果需要轉為字串輸出,不然會是一個物件,而不是 16 進位制字面值顯示的 32 位字串(由 0 - 9 和 a - f 組成)。
傳入CryptoJS.MD5()
的引數除了字串外,還可以是 CryptoJS 定義的一種叫做 WordArray 的資料型別。
const wordArray = CryptoJS.enc.Utf8.parse('2022JueJin') CryptoJS.MD5(wordArray).toString()
上面這段程式碼將 utf8 字串先轉成了 WordArray 物件,再將其傳給 CryptoJS.MD5()
,最終得到的結果如果列印輸出的話也是 84231025843afb62d818bf4f21612051。
enc 可以看成是 Encode(編碼) 的縮寫。Utf8
還能換成 Latin1
、Hex
和 Base64
等。如果想將一個 WordArray 物件轉換回 utf8 字元,可以執行
CryptoJS.enc.Utf8.stringify(wordArray)
一般情況下,訊息摘要演演算法得到的結果都是以 16 進位制字面值表示,如果想要得到 Base64,可以將加密結果通過 CryptoJS.enc.Base64.stringify()
轉換:
const base64 = CryptoJS.enc.Base64.stringify(CryptoJS.MD5('2022JueJin')) console.log(base64) // hCMQJYQ6+2LYGL9PIWEgUQ==
如果需要生成 MD5 的資料是個大檔案,一般我們可以把大檔案分為多段。採用下面的方式,先使用 CryptoJS.algo.MD5.create()
建立一個物件,命名為 hasher。然後將資料一段段的傳入 hasher.update()
處理:
const hasher = CryptoJS.algo.MD5.create() hasher.update('2022') hasher.update('JueJin') const hash = hasher.finalize() console.log(hash.toString())
最後呼叫 hasher.finalize()
表示傳輸完成,finalize()
裡也可以傳入資料。列印得到的結果也是 84231025843afb62d818bf4f21612051。如果想清除之前的 update,可以呼叫 hasher.reset()
。
上面介紹的單向雜湊函數嚴格來說並不是加密演演算法,更多是用於簽名。專案中需要進行加密的時候,最好採用下面介紹的加密演演算法。它們的加密和解密過程是可逆的,分為對稱加密和非對稱加密。
所謂對稱,指的是加密和解密使用的是相同的祕鑰,常見的有 DES、3DES 、RC4、RC5、RC6 和 AES。下面以我在公司最近的專案中使用的 AES 為重點進行介紹。
英文全稱為 Advanced Encryption Standard,即高階加密標準的意思。它的推出,用於取代已經被證明不安全的 DES 演演算法。AES 屬於分組加密演演算法,因為它會把傳入的明文資料以 128 bit 為一組分別處理。其祕鑰長度則可以是 128、192 和 256 bit。AES 或者說對稱加密演演算法的優點是速度快,缺點就是不安全,因為網站上的程式碼和祕鑰都是明文,別人只要得到了加密結果再結合祕鑰就能得到加密的資料了。
加密
我們將 “JueJin2022” 通過 AES 加密,得到的將是一個物件,我們需要通過 toString()
將其轉成字串輸出,最終得到的是一個以 base64 編碼的 “5yOOaUK1NSxVcRc8TA1fZw==”,程式碼如下:
const message = CryptoJS.enc.Utf8.parse('JueJin2022') const secretPassphrase = CryptoJS.enc.Utf8.parse('0123456789asdfgh') const iv = CryptoJS.enc.Utf8.parse('0123456789asdfgh') const encrypted = CryptoJS.AES.encrypt(message, secretPassphrase, { mode: CryptoJS.mode.CBC, paddding: CryptoJS.pad.Pkcs7, iv }).toString() console.log(encrypted)
CryptoJS.AES.encrypt()
可以傳入 3 個引數: 第 1 個為需要加密的明文; 第 2 個是祕鑰,長度可以是 128、192 或 256 bit; 第 3 個為一個設定物件,可以新增一些設定。常見的設定屬性有:
注意,明文、祕鑰和偏移向量一般先用諸如 CryptoJS.enc.Utf8.parse()
轉成 WordArray 物件再傳入,這樣做得到結果與不轉換直接傳入是不一樣的。
解密的寫法和加密差不多,只是把 encrypt
方法名改為 decrypt
,然後傳入的第 1 個引數由明文替換為密文,最後將之前轉換明文的方式傳入 toString()
即可:
const secretPassphrase = CryptoJS.enc.Utf8.parse('0123456789asdfgh') const iv = CryptoJS.enc.Utf8.parse('0123456789asdfgh') const decrypted = CryptoJS.AES.decrypt( '5yOOaUK1NSxVcRc8TA1fZw==', secretPassphrase, { mode: CryptoJS.mode.CBC, paddding: CryptoJS.pad.Pkcs7, iv: '0123456789asdfgh' } ).toString(CryptoJS.enc.Utf8) console.log(decrypted) // JueJin2022
注:如果之前在加密時沒有將明文進行 parse 而是直接傳入的,那麼在解密時,傳入 toString()
的解析方式就是寫預設的 CryptoJS.enc.Utf8
。
所謂的非對稱,即加密和解密用的不是同一個祕鑰。比如用公鑰加密,就要用私鑰解密。非對稱加密的安全性是要好於對稱加密的,但是效能就比較差了。
非對稱加密演演算法中常用的就是 RSA 了。它是由在 MIT 工作的 3 個人於 1977 年提出,RSA 這個名字的由來便是取自他們 3 人的姓氏首字母。我們在存取 github 等遠端 git 倉庫時,如果是使用 SSH 協定,需要生成一對公私祕鑰,就可以使用 RSA 演演算法。
我們依舊是採用 cdn 方式直接在頁面中引入 JSEncrypt 庫:
<script src="https://cdn.bootcdn.net/ajax/libs/jsencrypt/3.2.1/jsencrypt.min.js"></script>
使用的程式碼非常簡單。首先需要 new
一個範例物件出來,然後將通過 openssl 生成的公鑰傳給範例物件的 setKey
方法,之後只需要把要加密的明文傳給範例的 encrypt()
進行加密即可:
const crypt = new JSEncrypt() crypt.setKey('openssl 生成的公鑰') const text = 'JueJin2022' const enc = crypt.encrypt(text) console.log(enc)
生成的密文是一段 base64 格式的 1024 位 RSA 私鑰。
解密就是把私鑰傳給範例的 setKey()
,之後把密文傳給 decrypt()
進行解密即可:
const crypt = new JSEncrypt() crypt.setKey('openssl 生成的私鑰') const enc = 密文 const dec = crypt.decrypt(enc) console.log(dec)
注意,setKey 有 2 個別名: 如果傳入的是私鑰,可以用 setPrivateKey()
替換 setKey()
; 如果傳入的是公鑰,可以用 setPublicKey()
替換 setKey()
;
從上面的內容可知,JSEncrypt 的加解密過程需要用到 OpenSSL 來生成祕鑰,OpenSSL 是一個開源的軟體,它是對 SSL 協定的實現。能夠用於生成證書、證書籤名、生成祕鑰和加解密等。比如我公司最近的專案有個需求是要在本地開發時,localhost 使用 https 協定,就有用到 openssl。
可以去 slproweb.com/products/Wi… 選擇對應版本安裝:
然後在環境變數中新增設定,例如我把 openssl 安裝在了 D:OpenSSL-Win64,就將 D:OpenSSL-Win64bin 新增到 Path 中:
我們可以在想要儲存祕鑰的資料夾啟動命令列工具,並輸入以下命令生成祕鑰檔案:
openssl genrsa -out rsa_1024_priv.pem 1024
生成的祕鑰檔案如下:
可以通過 cat rsa_1024_priv.pem
檢視祕鑰內容,然後複製貼上給上面的 crypt.setKey()
。
注意:祕鑰必須寫成一行以 -----BEGIN PRIVATE KEY-----
開頭,以 -----END PRIVATE KEY-----
結尾。像下面這樣:
crypt.setKey( '-----BEGIN PRIVATE KEY-----MIICdFCQBj...中間省略...D3t4NbK1bqMA=-----END PRIVATE KEY-----')
生成上面的私鑰對應的公鑰的命令為
openssl rsa -pubout -in rsa_1024_priv.pem -out rsa_1024_pub.pem
檢視同樣是使用 cat
命令。
以上就是前端加密cryptojs與JSEncrypt使範例詳解的詳細內容,更多關於前端加密cryptojs JSEncrypt的資料請關注it145.com其它相關文章!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45