① 記錄一下前端使用CryptoJS的幾種加密方式
自己太小白了,之前在PC端項目中使用的MD5加密,現在的小程序項目使用了 CryptoJS 裡面的 enc-base64 和 hmac-sha1 ,之前沒有用到過這兩種,所以比較疑惑,為何在小程序不繼續使用 MD5 呢?所以在這里記錄一下自己解疑惑的一些知識點。
隨著互聯網的興起,我們對信息的安全越來越受重視,這樣就導致在web開發中,對用戶密碼等各種加密變得更加重要了。與伺服器的交互中,為了確保數據傳輸的安全性,避免被黑客抓包篡改。
對於Base64編碼的,我覺得看一篇文章能夠解決你的疑惑,我在這里就不贅述了
🧐 Base64編碼原理
如: 用戶密碼,請求參數,文件加密
如: 介面參數簽名驗證服務
支付數據、CA數字證書
前端的朋友可能會關注前端js加密,我們在做 WEB 的登錄功能時一般是通過 Form 提交或 Ajax 方式提交到伺服器進行驗證的。為了防止抓包,登錄密碼肯定要先進行一次加密(RSA),再提交到伺服器進行驗證。一些大公司都在使用,比如淘寶、京東、新浪 等。
前端加密也有很多現成的js庫,如:
JS-RSA: 用於執行OpenSSL RSA加密、解密和密鑰生成的Javascript庫, https://github.com/travist/jsencrypt
MD5: 單向散列加密md5 js庫, https://github.com/blueimp/JavaScript-MD5
crypto-js: 對稱加密AES js庫, https://github.com/brix/crypto-js
-CryptoJS (crypto.js) 為 JavaScript 提供了各種各樣的加密演算法。
HMAC 系列是消息驗證,用於驗證一個消息是否被篡改——如網站上傳遞 email 和 hmac(email),則接收時可以通過 hmac(email) 獲知 email 是否是用戶偽造的
② 前端js 加密解密方式
一、base64加密
使用JS函數的window.btoa()和 window.atob(),分別是中臘編碼和解碼
二、編碼和解碼字元串
使用JS函巧羨數賣寬滑的escape()和unescape(),分別是編碼和解碼
三、AES加密解密
四、RSA加密解密
③ jsencrypt實現前端RSA非對稱加密解密(vue項目)
最近一個vue項目要求所有密碼數據需要使用RSA非對稱加密傳輸,以為挺簡單,結果開發過程中還是遇到了些問題,簡單做個筆記。同時也希望可以幫助到遇到同樣問題的道友門。
重點來了:使用jsencrypt實現RSA非對稱加解密
因為這里直接在前端加解密,所以需要一對現成的密鑰,我們通過 密鑰在線生成器 得到:
然後在需要使用的文件中引入JSEncrypt,我是將所有工具函數都封裝在一個js文件的,我就直接在該文件中引入,我看也有人是在main.js中引入的。
到這里我們的加密解密方法就完成了,在需要的地方直接拿過來用就好了!
大功告成!這樣就完了?我以為這樣就ok了。
當然,如果沒有遇到這個bug,就可以忽略下面的內容了。
從上面截圖可以看到,重啟項目的時候報錯: navigator is not defined
而且這個bug有點奇葩,先啟動項目再引入jsencrypt就什麼問題都沒有,但是先引入jsencrypt再啟動項目就報錯。這也是我前面能順利執行的原因所在。
通過好一通折騰,用了網上的各種方法,比如在main.js引入jsencrypt、引入jsdom之類的,都沒能解決這個問題,最終還是在jsencrypt的git相關 issue 下找到了這個問題的解決方案。
到這里問題就算基本解決了,但是由於項目組不止我一個前端,我不能要求每個同事或者以後接手維護項目的同事都要在node_moles中去替換文件。
所以就採用了另外一種方案:將jsencrypt.js通過在線js壓縮器壓縮至jsencrypt.min.js中,然後把jsencrypt.min.js放到src/assets/jsencrypt文件夾中,就不用npm install的方式了。
換了種方式,jsencrypt的引用方式需要做出相應的調整:
參考鏈接: RSA非對稱加密傳輸---前端加密&解密(VUE項目)
https://github.com/travist/jsencrypt/issues/144
PS:才疏學淺,如果有考慮不周之處或者有更好的解決方案,歡迎指正探討!
④ RSA加密、解密、簽名、驗簽的原理及方法
RSA加密是一種非對稱加密。可以在不直接傳遞密鑰的情況下,完成解密。這能夠確保信息的安全性,避免了直接傳遞密鑰所造成的被破解的風險。是由一對密鑰來進行加解密的過程,分別稱為公鑰和私鑰。兩者之間有數學相關,該加密演算法的原理就是對一極大整數做因數分解的困難性來保證安全性。通常個人保存私鑰,公鑰是公開的(可能同時多人持有)。
加密和簽名都是為了安全性考慮,但略有不同。常有人問加密和簽名是用私鑰還是公鑰?其實都是對加密和簽名的作用有所混淆。簡單的說,加密是為了防止信息被泄露,而簽名是為了防止信息被篡改。這里舉2個例子說明。
RSA的加密過程如下:
RSA簽名的過程如下:
總結:公鑰加密、私鑰解密、私鑰簽名、公鑰驗簽。
RSA加密對明文的長度有所限制,規定需加密的明文最大長度=密鑰長度-11(單位是位元組,即byte),所以在加密和解密的過程中需要分塊進行。而密鑰默認是1024位,即1024位/8位-11=128-11=117位元組。所以默認加密前的明文最大長度117位元組,解密密文最大長度為128字。那麼為啥兩者相差11位元組呢?是因為RSA加密使用到了填充模式(padding),即內容不足117位元組時會自動填滿,用到填充模式自然會佔用一定的位元組,而且這部分位元組也是參與加密的。
⑤ 小程序RSA加密、解密、加簽、驗簽
npm install wxapp_rsa
var RSA = require('/wxapp_rsa.js')
// RSA加簽
var sign_rsa = new RSA.RSAKey();
//privateKey_pkcs1需要是-----BEGIN PRIVATE KEY-----開頭的私鑰
sign_rsa = RSA.KEYUTIL.getKey(privateKey_pkcs1);
console.log('簽名RSA:')
console.log(sign_rsa)
var hashAlg = 'MD5withRSA';
var hSig = sign_rsa.signString("12345678901234567890", hashAlg);
hSig = RSA.hex2b64(hSig); // hex 轉 b64
console.log("簽名結果:" + hSig)
// RSA 驗簽
var verify_rsa = new RSA.RSAKey();
verify_rsa = RSA.KEYUTIL.getKey(publicKey_pkcs1);
console.log('驗簽RSA:')
console.log(verify_rsa)
hSig = RSA.b64tohex(hSig)
var ver = verify_rsa.verifyString("12345678901234567890", hSig)
console.log('驗簽結果:' + ver)
// RSA加密 【加密欄位長度不大於117】
var encrypt_rsa = new RSA.RSAKey();
encrypt_rsa = RSA.KEYUTIL.getKey(rsa_public_key);
console.log('加密RSA:')
console.log(encrypt_rsa)
var encStr = encrypt_rsa.encrypt('1234567890')
console.log(encStr)
encStr = RSA.hex2b64(encStr);
console.log("加密結果:" + encStr)
// RSA 解密
var decrypt_rsa = new RSA.RSAKey();
decrypt_rsa = RSA.KEYUTIL.getKey(rsa_public_key_private);
console.log('解密RSA:')
console.log(decrypt_rsa)
encStr = RSA.b64tohex(encStr)
var decStr = decrypt_rsa.decrypt(encStr)
console.log("解密結果:" + decStr)
⑥ uni-app 利用Hbuilderx 的 rsa加密插件,實現加密
1.安裝插件,通過HbuilderX 導入插件
https://ext.dcloud.net.cn/plugin?id=1389
2.項目文件夾下,會自動生成一個文件夾,js_sdk,把最畢旦裡面的jsencrypt文件夾,拷貝到components下
3. 在需要參數加纖蠢密的vue頁面,引入該組件,就可以正常使用了
import jsencrypt from '@/components/jsencrypt/jsencrypt.vue';
onLoad(options){
var publiukey='-----BEGIN PUBLIC KEY-----'毀數陪+'/L5i2osbl8C9+WJTeucF+S76xFxdU6jE0NQ+Z+zEdhUTooNRaY5nZiu5PgDB0ED/' +'-----END PUBLIC KEY-----';
var pubblicData=jsencrypt.setEncrypt(publiukey,"1234");
console.log('密文',pubblicData);
}