js中常見的數據加密與解密的方法


加密在我們前端的開發中也是經常遇見的。本文只把我們常用的加密方法進行總結。不去糾結加密的具體實現方式(密碼學,太龐大了)。

常見的加密方式

常見的加密算法基本分為這幾類,

  1. 線性散列算法(簽名算法)MD5 SHA1
  2. 對稱性加密算法 AES DES
  3. 非對稱性加密算法 RSA

Md5加密

  • MD5是一種被廣泛使用的線性散列算法,可以產生出一個128位(16字節)的散列值(hash value),用於確保信息傳輸完整一致。

  • MD5加密之后產生的是一個固定長度(32位或16位)的數據

  • MD5是可以進行反向暴力破解的。也就是用很多不同的數據進行加密后跟已有的加密數據進行對比。理論上只要數據量足夠龐大MD5是可以被破解的

  • MD5考慮的是破解的成本(時間和機器性能)。假設破解當前的MD5密碼需要目前計算能力最優秀的計算機工作100年才能破解完成。那么當前的MD5密碼就是安全的。

  • 增加破解成本的方法(方法很多,這里只說我常用的)。

    1. 使用一段無意義且隨機的私匙進行MD5加密會生成一個加密串,我們暫且稱之為串1
    2. 將要加密的的數據跟串1拼接,再進行一次MD5,這時會生成串2
    3. 將串2再次進行MD5加密,這時生成的串3就是我們加密后的數據。
  • 解密。MD5不存在解密。只能把數據進行相同的MD5處理之后跟之前的的加密串進行對比。

  • 我們在注冊賬號時的密碼一般都是用的MD5加密。

  • js中使用MD5

    多說無益直接上代碼

  <script src="https://cdn.bootcss.com/blueimp-md5/2.10.0/js/md5.js"></script> var hash = md5("111111"); // "96e79218965eb72c92a549dd5a330112" 
 
WX20190529-170424.png

RSA加密

RSA加密:RSA加密算法是一種非對稱加密算法。在公開密鑰加密和電子商業中RSA被廣泛使用。(這才是正經的加密算法)

非對稱加密算法:非對稱加密算法需要兩個密鑰:公開密鑰(publickey:簡稱公鑰)和私有密鑰(privatekey:簡稱私鑰)。公鑰與私鑰是一對,如果用公鑰對數據進行加密,只有用對應的私鑰才能解密。因為加密和解密使用的是兩個不同的密鑰,所以這種算法叫作非對稱加密算法。

  • 使用時都是使用公匙加密使用私匙解密。公匙可以公開,私匙自己保留。
  • 算法強度復雜、安全性依賴於算法與密鑰但是由於其算法復雜,而使得加密解密速度沒有對稱加密解密的速度快。
  • 使用場景介紹
    • 通過公匙加密,使用私匙解密。私匙是通過公匙計算生成的。假設ABC三方之間相互要進行加密通信。大家相互之間使用公匙進行信息加密,信息讀取時使用各自對應的私匙進行信息解密
  • 公私匙可以通過http://web.chacuo.net/netrsakeypair在線生成
  • 用戶輸入的支付密碼會通過RSA加密
    <script src="https://cdn.bootcss.com/jsencrypt/3.0.0-beta.1/jsencrypt.js"></script> <script type="text/javascript"> //公鑰 var PUBLIC_KEY = 'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCADB+zg4Ou3fv6rY8159gw4fkJbuMPeM41ttw20leKjSKQWOgBixHJjXbkRvoMmUQkWq67xWzpMgKB7t8LIJx+n0dLP+6YDqbfFEJJ2i1Va4U1yJyGht0bEW0tpadKX3i5JwUwQIBPiC7VSWhtVyAKtzTYeun/fqpxTDAbulrj4QIDAQAB'; //私鑰 var PRIVATE_KEY = 'MIICWwIBAAKBgQCADB+zg4Ou3fv6rY8159gw4fkJbuMPeM41ttw20leKjSKQWOgBixHJjXbkRvoMmUQkWq67xWzpMgKB7t8LIJx+n0dLP+6YDqbfFEJJ2i1Va4U1yJyGht0bEW0tpadKX3i5JwUwQIBPiC7VSWhtVyAKtzTYeun/fqpxTDAbulrj4QIDAQABAoGACj/Y2m0orBAfvHvfrpBtc9LlX2sX/g6M7wFr6hrMdWOBBJiL5Z0PTO39D3Ow +IjcyqN+62UiUnOK04IJKiJaSa1HNWagW2aAOblca1lYyYD6wlUotMV3bgk9lly0dD0lUTd8XWOmo1NdTEFW7y1OB4pYgMcT+iv4o0cr4sAtWisCQQCD6EmjEpMI5dcfZcrSXbT+WQGvdVCjAhivVMbNYeZq37ARt+9mTnaoA6Ss/QGQ5qvO9jMhx8x9/e8EfA+AX2rzAkEA+II3IXRXY3xbjDnK84kunlWpImH6XofN2V/TGEH1/Iqa909PHhuL4mhSt0iC70/y1g5kbmXyXE5s5gEsPqmC2wJAAU9uY9NMaJs33tT5Bcvuf1RNAvwsV+Iucpdp/iJJ0qf0LMjh9Oc0oIiguyMsP886x6yEZ4J/koTSOf4tfT31ZwJAMs28I5S7QNVtic9O1FbZNvlgKG1LWAP/a08RwsXJWiWj5KdMD2WmRVT6hAnI6s+3X1d15LPmxkQqMyNOPkk9PQJAJyPGWOjrCjzwojE0lN4NtS9brx6JbPy/sFkHX5LN8Xv45+XOKp14JgRcABTfWfvnnoWoWKha2cyJFlf8AdCIuQ=='; //使用公鑰加密 var encrypt = new JSEncrypt(); //encrypt.setPrivateKey('-----BEGIN RSA PRIVATE KEY-----'+PRIVATE_KEY+'-----END RSA PRIVATE KEY-----'); encrypt.setPublicKey('-----BEGIN PUBLIC KEY-----' + PUBLIC_KEY + '-----END PUBLIC KEY-----'); var encrypted = encrypt.encrypt('ceshi01'); console.log('加密后數據:%o', encrypted); //使用私鑰解密 var decrypt = new JSEncrypt(); //decrypt.setPublicKey('-----BEGIN PUBLIC KEY-----' + PUBLIC_KEY + '-----END PUBLIC KEY-----'); decrypt.setPrivateKey('-----BEGIN RSA PRIVATE KEY-----'+PRIVATE_KEY+'-----END RSA PRIVATE KEY-----'); var uncrypted = decrypt.decrypt(encrypted); console.log('解密后數據:%o', uncrypted); </script> 

jsencrypt文件在小程序環境appName報錯的問題

  • 原因是在小程序環境下沒有瀏覽器環境的navigator對象和window對象
  •  

     

    解決辦法修改源碼,具體見下圖
     
    WX20191106-113845.png
var navigator2 = { appName: 'Netscape', userAgent: 'Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1' }; var window2 = { ASN1: null, Base64: null, Hex: null, crypto: null, href: null }; let navigator = navigator2 let window = window2 

DES/AES加密

DES全稱為Data Encryption Standard,即數據加密標准,是一種使用密鑰加密的塊算法

DES算法的入口參數有三個:Key、Data、Mode。其中Key為7個字節共56位,是DES算法的工作密鑰;Data為8個字節64位,是要被加密或被解密的數據;Mode為DES的工作方式,有兩種:加密或解密。

AES這個標准用來替代原先的DES

DES/AES我們合並在一起介紹其用法和特點

  • DES/AES是一種對稱加密方式,加密運算、解密運算使用的是同樣的密鑰
  • 使用DES/AES進行數據交互時要求雙方都擁有相同的私匙
  • 破解方法,暴力破解。DES 使用 56 位的密鑰,則可能的密鑰數量是 2 的 56 次方個。只要計算足夠強大是可以被破解的
  • js中的使用方法
<script src="https://cdn.bootcss.com/crypto-js/3.1.9-1/crypto-js.js"></script> <script> var aseKey = "12345678" //秘鑰必須為:8/16/32位 var message = "我是一個密碼"; //加密 DES/AES切換只需要修改 CryptoJS.AES <=> CryptoJS.DES var encrypt = CryptoJS.AES.encrypt(message, CryptoJS.enc.Utf8.parse(aseKey), { mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.Pkcs7 }).toString(); console.log(encrypt); // 0Gh9NGnwOpgmB525QS0JhVJlsn5Ev9cHbABgypzhGnM //解密 var decrypt = CryptoJS.AES.decrypt(encrypt, CryptoJS.enc.Utf8.parse(aseKey), { mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.Pkcs7 }).toString(CryptoJS.enc.Utf8); console.log(decrypt); // 我是一個密碼 </script> 

base64偽加密

Base64是一種用64個字符來表示任意二進制數據的方法。base64是一種編碼方式而不是加密算法。只是看上去像是加密而已(嚇唬人)。

  1. base64原理
  • Base64使用A--Z,a--z,0--9,+,/ 這64個字符。
  • 將3個字節轉換成4個字節( (3 X 8) = 24 = (4 X 6) )先讀入3個字節,每讀一個字節,左移8位,再右移四次,每次6位,這樣就有4個字節了。
  1. js中的應用
var Base64 = { _keyStr: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=", encode: function(e) { var t = ""; var n, r, i, s, o, u, a; var f = 0; e = Base64._utf8_encode(e); while (f < e.length) { n = e.charCodeAt(f++); r = e.charCodeAt(f++); i = e.charCodeAt(f++); s = n >> 2; o = (n & 3) << 4 | r >> 4; u = (r & 15) << 2 | i >> 6; a = i & 63; if (isNaN(r)) { u = a = 64 } else if (isNaN(i)) { a = 64 } t = t + this._keyStr.charAt(s) + this._keyStr.charAt(o) + this._keyStr.charAt(u) + this._keyStr.charAt(a) } return t }, decode: function(e) { var t = ""; var n, r, i; var s, o, u, a; var f = 0; e=e.replace(/[^A-Za-z0-9+/=]/g,""); while (f < e.length) { s = this._keyStr.indexOf(e.charAt(f++)); o = this._keyStr.indexOf(e.charAt(f++)); u = this._keyStr.indexOf(e.charAt(f++)); a = this._keyStr.indexOf(e.charAt(f++)); n = s << 2 | o >> 4; r = (o & 15) << 4 | u >> 2; i = (u & 3) << 6 | a; t = t + String.fromCharCode(n); if (u != 64) { t = t + String.fromCharCode(r) } if (a != 64) { t = t + String.fromCharCode(i) } } t = Base64._utf8_decode(t); return t } } // 定義字符串 var string = 'Hello World!'; // 加密 var encodedString = Base64.encode(string); console.log(encodedString); // 輸出: "SGVsbG8gV29ybGQh" // 解密 var decodedString = Base64.decode(encodedString); console.log(decodedString); // 輸出: "Hello World!"


鏈接:https://www.jianshu.com/p/95d8eeb8301f


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM