JS使用 cryptojs加密解密(對稱加密庫)的問題
js 加密解密可以使用 crypto-js
這是一個對稱加密的庫, 可以使用 AES DES 但沒有 rsa 等非對稱加密的方法
安裝方法 npm install crypto-js
它可以進行 MD5 SHA-1 SHA-256 Base64 AES DES 等算法和加密
import crypto from "crypto-js" let md5binary = crypto.MD5("message"); let hamcmd5binary =crypto.HmacMD5("message"); //以上兩個得到的是一個二進制的數(shù)據(jù), 要可打印出業(yè),就要使用 16進制模式或者base64方式 //crypto 也有應的轉(zhuǎn)換方法
通過顯式調(diào)用toString方法并傳遞編碼器,可以將WordArray(二進制數(shù)據(jù))對象轉(zhuǎn)換為其他格式。
import crypto from "crypto-js" let md5message = cryptjs.MD5(str); //這里得到的都是摘要的 二進制數(shù)據(jù) console.log(md5message); //打印的二進制數(shù)據(jù) let hmacmd5message = cryptjs.HmacMD5(str,"haha"); //這里得到的都是摘要的 二進制數(shù)據(jù) console.log(hmacmd5message); //打印的二進制數(shù)據(jù) let sha1message = cryptjs.SHA1(str); //這里得到的都是摘要的 二進制數(shù)據(jù) console.log(sha1message); //打印的二進制數(shù)據(jù) let hamcsha1message = cryptjs.HmacSHA1(str,"haha");//這里得到的都是摘要的 二進制數(shù)據(jù) console.log(hamcsha1message); //打印的二進制數(shù)據(jù) let sha512message = cryptjs.SHA512(str); //這里得到的都是摘要的 二進制數(shù)據(jù) console.log(sha512message); //打印的二進制數(shù)據(jù) let hmacsha512message = cryptjs.HmacSHA512(str,"haha");//這里得到的都是摘要的 二進制數(shù)據(jù) console.log(hmacsha512message);//打印的二進制數(shù)據(jù) //上面打印的都是二進制的數(shù)據(jù), 不利于傳輸, 所以, 我們要把它們變成 十六進制數(shù)據(jù),或都base64的數(shù)據(jù)來進行傳輸 //通過顯式調(diào)用toString方法并傳遞編碼器,可以將WordArray(二進制)對象轉(zhuǎn)換為其他格式。 //轉(zhuǎn)成 base64 格式的方法 let strbyhex = md5message.toString(cryptjs.enc.Hex); //把二進制數(shù)據(jù)轉(zhuǎn)成16進制 console.log(strbyhex,"|||||||| js 十六進制結(jié)果"); let strbybase64 = md5message.toString(cryptjs.enc.Base64); //把二進制數(shù)據(jù)轉(zhuǎn)成base64 console.log(strbybase64,"||||||||js base64 結(jié)果")
我們把最后幾行的 二進制轉(zhuǎn)16進制和 二進制轉(zhuǎn)base64 的結(jié)果和 php 生成的結(jié)果對比一下看看
public function testpass(){ $md5binary = hash("md5","message",true); //第三個參數(shù) 為false 輸出的是十六進制數(shù)據(jù) 如果是true 輸出的是二進制數(shù)據(jù) //php 轉(zhuǎn)二進制數(shù)據(jù)到 十六進制數(shù)據(jù) $md5hex = bin2hex($md5binary); //php 二進制數(shù)據(jù)到base64 $md5base64 = base64_encode($md5binary); echo "php十六進制結(jié)果"; echo $md5hex; echo "<br/>"; echo "php base64結(jié)果"; echo $md5base64; }
分別運行代碼看結(jié)果
對比沒有問題
對稱加密
cryptojs 也可以用來做對稱加密,就拿 AES 對稱加密來說
AES 對稱加密是 需要有 密鑰key 向量 iv
CryptoJS支持AES-128、AES-192和AES-256。它會根據(jù)你傳入的密鑰的大小來選擇變體。如果你使用密碼短語,它會生成一個256位的密鑰。
當然, 我們也可以自己來定義 密鑰key 和 iv向量
在這之前我們要先了解一下, js base64 16進制 utf8 之前的轉(zhuǎn)換
js php utf8字符串轉(zhuǎn)base64
let str = "這是一個測式"; let words = cryptjs.enc.Utf8.parse(str); //先把字符串轉(zhuǎn)成words數(shù)型的二進制數(shù)組 let base64words = cryptjs.enc.Base64.stringify(words); //把二進制數(shù)組轉(zhuǎn)成 base64字符串 console.log(base64words); //輸出 6L+Z5piv5LiA5Liq5rWL5byP
我們可以用 php base64_encode 來驗證一下
$a = "這是一個測式"; echo base64_encode($a); //輸出的結(jié)果 6L+Z5piv5LiA5Liq5rWL5byP
js php 把base64字符轉(zhuǎn)成 utf8
let baseStr = "6L+Z5piv5LiA5Liq5rWL5byP"; let wordsbyBase64 = cryptjs.enc.Base64.parse(baseStr); //把base64字符串轉(zhuǎn)成 words數(shù)組(二進制數(shù)組) let res = cryptjs.enc.Utf8.stringify(wordsbyBase64); console.log(res); //結(jié)果 這是一個測式
php base64_decode 來驗證
$a = "6L+Z5piv5LiA5Liq5rWL5byP"; echo base64_decode($a); // 結(jié)果 這是一個測式
js php 把utf8 字符串,轉(zhuǎn)成16進制
let str1 = "這是一個字符串轉(zhuǎn)成十六進制的測試"; let words16bystr = cryptjs.enc.Utf8.parse(str1); let hexstr = cryptjs.enc.Hex.stringify(words16bystr); console.log(hexstr); //得到結(jié)果 e8bf99e698afe4b880e4b8aae5ad97e7aca6e4b8b2e8bdace68890e58d81e585ade8bf9be588b6e79a84e6b58be8af95
用 php 來進行驗證
$str = "這是一個字符串轉(zhuǎn)成十六進制的測試"; $strto16 = bin2hex($str); echo $strto16; //結(jié)果 e8bf99e698afe4b880e4b8aae5ad97e7aca6e4b8b2e8bdace68890e58d81e585ade8bf9be588b6e79a84e6b58be8af95
此處有點疑問:明明是一個字符串, 為什么php 轉(zhuǎn)換時用的 bin2hex 函數(shù)呢,這不應該是二進制數(shù)據(jù)轉(zhuǎn)hex 才用的函數(shù)嗎?
后來,我使用 php 的gettype 函數(shù) 看了一下,不管是字符串,還是二進制數(shù)據(jù), 在php 這里都是string 類型, 也就是說 php 底層是把 字符串當做二進制的數(shù)據(jù)在處理(這里不知道對不對,感覺是這樣的)
$str = "這是一個字符串轉(zhuǎn)成十六進制的測試"; echo gettype($str); // 顯示 string echo "<br/>"; //為了得到一個二進制的亂碼一樣的數(shù)據(jù), 我們可以使用 hash函數(shù)得到 //hash 第三個參數(shù)如果設為 true ,就可以得到一個二進制數(shù)據(jù) $binary = hash("md5","123456",true); echo $binary; // 顯示 ? ?9I?Y??V?W??> echo gettype($binary); // 顯示 string 但這個明顯是一些亂碼
從上面的例子中, 我們看到 其實 $str 和 $binary 都是一個類型的(string,底層看他們都是二進制數(shù)據(jù)),那么為什么 一個可以顯示正常,一個顯示亂碼呢,
因為 $str 是我們輸入的中文字符, 在字符碼表中一定是有想應的編碼的,但是 $binary 就是一串無序的二進制數(shù), 有的可能中文碼表中根本就沒有對應的字符,所以就顯示成亂碼了
因為有的會顯示成亂碼, 所以我們在傳輸?shù)臅r候,可以使用 base64來傳輸,把二進制數(shù)據(jù)轉(zhuǎn)成 base64,傳輸,不會丟失數(shù)據(jù)
js php 把16進制數(shù)據(jù)轉(zhuǎn)成 utf8 字符串
let str2 = "e8bf99e698afe4b880e4b8aae5ad97e7aca6e4b8b2e8bdace68890e58d81e585ade8bf9be588b6e79a84e6b58be8af95"; let hextowords = cryptjs.enc.Hex.parse(str2); //把十六進制轉(zhuǎn)成 words (二進制數(shù)組) let str2back = cryptjs.enc.Utf8.stringify(hextowords); //把二進制轉(zhuǎn)成utf8 console.log(str2back);
php 驗證
$hexstr = 'e8bf99e698afe4b880e4b8aae5ad97e7aca6e4b8b2e8bdace68890e58d81e585ade8bf9be588b6e79a84e6b58be8af95'; $str = hex2bin($hexstr); echo $str;
有了上面的基礎, 我們下面來做一個例子
由后端php 使用 對稱加密,加密一段文字, 然后返回給前端js , 同時要返回 加密的 iv, 然后前端 js 使用 cryptojs 來進行解密, 看是否正確 js AES 加解密
cryptjs.AES.encrypt 參數(shù)中的 key 和 iv 都是 以 wordsArray (二進制) 傳入的,所以要明白 Utf8.parse 的方法
CryptoJS支持AES-128、AES-192和AES-256。它會根據(jù)你傳入的密鑰的大小來選擇變體。
所以 下例中, 我們的 key1 只有16位,所以會自動選用 aes-128
//加密 let secretStr = "這是一個測試AES"; let key1 = cryptjs.enc.Utf8.parse("1234567812345678"); //十六位的 let encrypted1 = cryptjs.AES.encrypt(secretStr,key1,{ iv:cryptjs.enc.Utf8.parse("abcdefghijklmnop"), mode:cryptjs.mode.CBC, //aes加密模式cbc 這個參數(shù)要前后端一至使用統(tǒng)一的加密模式 padding:cryptjs.pad.Pkcs7 //使用 Pkcs7的方式填充 //這個php 加密時默認就是這種方式 }); console.log(encrypted1); //加密的結(jié)果是一個對象 console.log(encrypted1.key); //對象中有 key , iv 等信息 console.log(cryptjs.enc.Utf8.stringify(encrypted1.key)) //打印出key 的utf8字符串 console.log(encrypted1.toString()) //使用toString 方法可以得到加密后的字符串 //加密的結(jié)果是: YzXNRYB6/mmevnBiZPLRPu4Knk+qUVNyhUKonAB2Wjg= 這明顯是一個base64格式的 //解密 let result = cryptjs.AES.decrypt(encrypted1.toString(),key1,{ iv:cryptjs.enc.Utf8.parse("abcdefghijklmnop"), mode:cryptjs.mode.CBC, padding:cryptjs.pad.Pkcs7 }) console.log(result); //解密后得到的是一個 wordArray 二進制的對象 console.log(cryptjs.enc.Utf8.stringify(result)); //把二進制對象轉(zhuǎn)成 utf8的字符 //解密的結(jié)果是 這是一個測試AES
php AES 加解密
$str = "這是一個測試AES"; $algo = "AES-128-CBC"; dump(openssl_cipher_iv_length($algo)); //這里我們可以先看一下 AES-128-CBC 的所需要的 iv 長度 結(jié)果是16,所以我們自定義了一個iv 是16個字符 $key = "1234567812345678"; $iv = "abcdefghijklmnop"; $encrypt = openssl_encrypt($str,$algo,$key,OPENSSL_RAW_DATA,$iv); echo $encrypt; //顯示結(jié)果 YzXNRYB6/mmevnBiZPLRPu4Knk+qUVNyhUKonAB2Wjg= echo "<br/>"; $decrypt = openssl_decrypt($encrypt,$algo,$key,OPENSSL_RAW_DATA,$iv); echo $decrypt;
從上面可以看到 js 和 php 加密的結(jié)果是一樣的,那么就說明 前端js 和 后端php也是可以互通加解密的
到此這篇關(guān)于js 加密解密 cryptojs(對稱加密庫)的文章就介紹到這了,更多相關(guān)js 加密解密 cryptojs內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- js前端加密庫Crypto-js進行MD5/SHA256/BASE64/AES加解密的方法與示例
- JavaScript實現(xiàn)的前端AES加密解密功能【基于CryptoJS】
- JS使用插件cryptojs進行加密解密數(shù)據(jù)實例
- VueJs里利用CryptoJs實現(xiàn)加密及解密的方法示例
- 使用JS前端加密庫sm-crypto實現(xiàn)國密sm2、sm3和sm4加密與解密
- 前端CryptoJS加密、后端JAVA解密代碼實現(xiàn)參考
- vue項目中使用crypto-js實現(xiàn)加密解密方式
- vue項目之前端CryptoJS加密、解密代碼示例
- vue用CryptoJS加密,java用CryptoUtil解密
- crypto-js對稱加密解密的使用方式詳解(vue與java端)
相關(guān)文章
js一般方法改寫成面向?qū)ο蠓椒ǖ臒o限級折疊菜單示例代碼
本例是應用別人的例子,原來那位老兄是用一般方法寫成的無限級折疊菜單,通過了一些簡化修改,將原來的例子改成了面向?qū)ο蟮姆绞?/div> 2013-07-07JS+CSS實現(xiàn)分類動態(tài)選擇及移動功能效果代碼
這篇文章主要介紹了JS+CSS實現(xiàn)分類動態(tài)選擇及移動功能效果代碼,涉及JavaScript實現(xiàn)頁面元素動態(tài)變換效果實現(xiàn)技巧,具有一定參考借鑒價值,需要的朋友可以參考下2015-10-10JavaScript toDataURL圖片轉(zhuǎn)換問題解讀
這篇文章主要介紹了JavaScript toDataURL圖片轉(zhuǎn)換問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-06-06JS結(jié)合bootstrap實現(xiàn)基本的增刪改查功能
這篇文章主要介紹了JS結(jié)合bootstrap實現(xiàn)基本的增刪改查功能,需要的朋友可以參考下2016-07-07javascript數(shù)組按屬性分組實現(xiàn)方法
在開發(fā)過程中,前端有時需要對后端返回的數(shù)據(jù)進行一些處理,當后端返回給我們json對象數(shù)組時,我們可能會需要按照對象中的某一個屬性來進行分組,下面這篇文章主要給大家介紹了關(guān)于javascript數(shù)組按屬性分組的實現(xiàn)方法,需要的朋友可以參考下2023-05-05uni-app微信小程序登錄授權(quán)的實現(xiàn)
這篇文章主要介紹了uni-app微信小程序登錄授權(quán)的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-05-05JS動態(tài)添加Table的TR,TD實現(xiàn)方法
這篇文章主要介紹了JS動態(tài)添加Table的TR,TD實現(xiàn)方法,涉及js針對Table中TR、TD節(jié)點的操作技巧,具有一定參考借鑒價值,需要的朋友可以參考下2015-01-01最新評論