JavaScript的加密和解密用的是google的CryptoJS庫。本文以AES/ECB/NoPadding爲例展現AES加密和解密的方法。html
須要下載CryptoJS庫,下載地址以下:
https://github.com/sytelus/CryptoJSgit
須要引入庫文件:
<script src="./CryptoJS-master/rollups/aes.js"></script>
<script src="./CryptoJS-master/components/mode-ecb.js"></script>
<script src="./CryptoJS-master/components/pad-nopadding.js"></script>github
加密方法:數組
function encrypt(str) { var decArray = hexStrToDecArray(str); var wordArray = int8parse(decArray); var encrypted = CryptoJS.AES.encrypt(wordArray, aesKeyBytes(), { mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.NoPadding }); return wordArrayToHexStr(encrypted.ciphertext.words); }
這個方法傳入的是十六進制字符串,格式爲"AA BB CC DD EE FF";
hexStrToDecArray()方法用來將十六進制字符串轉換成十進制數字的數組;
int8parse()方法用來將十進制數字轉換成CryptoJS所須要的wordArray數組;
最後,encrypt()方法加密獲得的是一個wordArray數組,wordArrayToHexStr()再將其解析成十六進制字符串。瀏覽器
解密方法:測試
function decrypt(str) { var decArray = hexStrToDecArray(str); var wordArray = int8parse(decArray); var base64Str = CryptoJS.enc.Base64.stringify(wordArray); var decrypted = CryptoJS.AES.decrypt(base64Str, aesKeyBytes(), { mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.NoPadding }); return wordArrayToHexStr(decrypted.words); }
解密方法同加密方法相似,可是CryptoJS.AES.decrypt()方法須要傳入Base64格式的加密字符串,所以這裏須要先使用CryptoJS.enc.Base64.stringify()方法作一次轉換。google
如下是完整的Demo代碼:加密
<!DOCTYPE html> <html> <head> <script src="./CryptoJS-master/rollups/aes.js"></script> <script src="./CryptoJS-master/components/mode-ecb.js"></script> <script src="./CryptoJS-master/components/pad-nopadding.js"></script> <script> function encryptText() { var plain = document.getElementById("plain").value; console.log("plain: " + plain); var encrypted = encrypt(plain); console.log("encrypted: " + encrypted); document.getElementById("encrypted").value = encrypted; } function decryptText() { var encrypted = document.getElementById("todecrypt").value; console.log("encrypted: " + encrypted); var decrypted = decrypt(encrypted); console.log("decrypted: " + decrypted); document.getElementById("decrypted").value = decrypted; } // 加解密用到的密鑰 function aesKeyBytes() { var key_Int = new Int8Array([65, 144, 48, 53, 18, 52, 86, 120, 131, 116, 124, 139, 237, 203, 169, 135]); var keyBytes = int8parse(key_Int); return keyBytes; } // 十六進制字符串數組,個數若是不足16整數倍則補0 function hexTo16Hex(str) { var diff = 16 - (str.length + 1) / 3 % 16; for(var i = 0; i < diff; i++) { str = str + " 00"; } return str; } // AES加密 function encrypt(str) { var decArray = hexStrToDecArray(str); var wordArray = int8parse(decArray); var encrypted = CryptoJS.AES.encrypt(wordArray, aesKeyBytes(), { mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.NoPadding }); return wordArrayToHexStr(encrypted.ciphertext.words); } // AES解密 function decrypt(str) { var decArray = hexStrToDecArray(str); var wordArray = int8parse(decArray); var base64Str = CryptoJS.enc.Base64.stringify(wordArray); var decrypted = CryptoJS.AES.decrypt(base64Str, aesKeyBytes(), { mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.NoPadding }); return wordArrayToHexStr(decrypted.words); } // 構建WordArray對象 function int8parse(u8arr) { var len = u8arr.length; var words = []; for (var i = 0; i < len; i++) { words[i >>> 2] |= (u8arr[i] & 0xff) << (24 - (i % 4) * 8); } return CryptoJS.lib.WordArray.create(words, len); } // 十六進制字符串(空格分割)轉成十進制數字的數組 function hexStrToDecArray(str) { var strArray = str.split(" "); var decArray = []; for(var i = 0; i < strArray.length; i++) { decArray.push(parseInt(strArray[i], 16)); } return arrayTo16Array(decArray); } // 十進制數組轉成十六進制字符串 function decArrayToHexStr(array) { var hexStr = ""; for(var i = 0; i < array.length; i++) { var str = array[i].toString(16).toUpperCase(); if (str.length < 2) { str = "0" + str; } hexStr = hexStr + str + " "; } return hexStr.substr(0, hexStr.length - 1); } // word類型的十進制數組轉成十六進制字符串 function wordArrayToHexStr(array) { var hexStr = ""; for(var i = 0; i < array.length; i++) { var num = array[i]; if (num < 0) { num = array[i] + 0x100000000; } var str = num.toString(16).toUpperCase(); var fullStr = str; if (str.length < 8) { for(var j = 0; j < 8 - str.length; j++) { fullStr = "0" + fullStr; } } hexStr = hexStr + fullStr; } var ret = ""; for(var i = 0; i < hexStr.length; i += 2) { ret = ret + hexStr.substr(i, 2) + " " } return ret.substr(0, ret.length - 1); } // 數組元素個數必須是16的整數倍,不足的在後面補0 function arrayTo16Array(array) { var len = array.length; var distLen = parseInt((array.length - 1) / 16) * 16 + 16; for(var i = array.length; i < distLen; i++) { array[i] = 0; } return array; } </script> </head> <body> <h1>加解密測試</h1> AES128,ECB模式,PaddingModeZeros,不足部分補0 <br> <input id="plain" type="text" style="width:500px; height:20px;"/> <button type="button" onclick="encryptText()">加密</button> <input id="encrypted" type="text" style="width:500px; height:20px;" /> <br> <br> <br> <input id="todecrypt" type="text" style="width:500px; height:20px;"/> <button type="button" onclick="decryptText()">解密</button> <input id="decrypted" type="text" style="width:500px; height:20px;" /> </body> </html>
在瀏覽器中打開以後效果以下:
輸入要加密或解密的字符串,點擊加密/解密按鈕便可。spa