使用crypto-js在瀏覽器上對數據加密簽名
重要知識點:
- CryptoJS.lib.WordArray WordArray對象可以理解為byte[]
- CryptoJS.enc 提供編碼轉換,從字符串轉為WordArray,或從WordArray轉為字符串
MD5加密
var ciphetext = CryptoJS.MD5(plaintext);//獲得一個CryptoJS.lib.WordArray對象 ciphetext.toString(CryptoJS.enc.Base64);//轉成Base64字符串,也可以用 CryptoJS.enc.Base64.stringify(ciphetext); //ciphetext.toString(); //默認轉成BitString格式,與ciphetext.toString(CryptoJS.enc.Hex);效果相同
完整代碼

<html> <head> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js" type="text/javascript"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.9-1/crypto-js.min.js" type="text/javascript"></script> <title>MD5 加密解密</title> <script type="text/javascript"> function encryptor() { var plaintext = $("#plaintext").val(); var displayFormat = $("#displayFormat").val(); var ciphetext = CryptoJS.MD5(plaintext); switch (displayFormat) { case "Base64String": ciphetext = CryptoJS.enc.Base64.stringify(ciphetext); break; case "BitString": ciphetext = CryptoJS.enc.Hex.stringify(ciphetext); break; } $("#ciphetext").val(ciphetext); } </script> <style> h, div { margin: 10px 10px; } input[type=text] { width: 500px; } input[type=button] { margin: 0px 5px; padding: 10px; } select { width: 250px; } textarea { width: 500px; height: 150px; } </style> </head> <body> <div> <div> <h>MD5 加密解密</h> </div> <div> <label for="plaintext">明文:</label> <br /> <textarea id="plaintext"></textarea> </div> <div> <label for="plaintext">顯示格式:</label> <br /> <select id="displayFormat"> <option value="Base64String" selected="selected">Base64String</option> <option value="BitString">BitString</option> </select> </div> <div> <input type="button" value="加密" onclick="encryptor()" /> </div> <div> <label for="ciphetext">密文:</label> <br /> <textarea id="ciphetext" readonly="readonly" ></textarea> </div> </div> </body> </html>
HmacSha1 簽名
var signtext = '這里是你的簽名'; var converttext ='這里是正文,被簽名的文本'; signtext = CryptoJS.enc.Utf8.parse(signtext);//得到一個CryptoJS.lib.WordArray對象 converttext = CryptoJS.enc.Utf8.parse(converttext);//得到一個CryptoJS.lib.WordArray對象 var resulttext = CryptoJS.HmacSHA1(converttext, signtext); //得到一個CryptoJS.lib.WordArray對象,這就是你的簽名 resulttext=resulttext.toString();//轉成BitString格式
完整代碼

<html> <head> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js" type="text/javascript"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.9-1/crypto-js.min.js" type="text/javascript"></script> <title>HmacSha1 簽名</title> <script type="text/javascript"> $(function () { $("#buttonSign").bind("click", Sign); $("#buttonVerifySign").bind("click", VerifySign); }); </script> <script type="text/javascript"> function Sign() { var signtext = $("#signtext").val(); var converttext = $("#converttext").val(); signtext = GetWordArray(signtext); converttext = CryptoJS.enc.Utf8.parse(converttext); var resulttext = CryptoJS.HmacSHA1(converttext, signtext); resulttext = resulttext.concat(converttext); $("#resulttext").val(WrodArrayToString(resulttext)); } function VerifySign() { var signtext = $("#signtext").val(); var converttext = $("#converttext").val(); signtext = GetWordArray(signtext); converttext = GetWordArray(converttext); var signtext1 = GetSign(converttext); var resulttext = GetCiphetext(converttext); var signtext2 = CryptoJS.HmacSHA1(resulttext, signtext) var b = WrodArrayToString(signtext1) == WrodArrayToString(signtext2); if (b) { $("#resulttext").val(CryptoJS.enc.Utf8.stringify(resulttext)); } else { $("#resulttext").val("驗證失敗"); } } function GetSign(wordArray) { var words = wordArray.words; var sigBytes = wordArray.sigBytes; words = words.slice(0, 5); return new CryptoJS.lib.WordArray.init(words, 20); } function GetCiphetext(wordArray) { var words = wordArray.words; var sigBytes = wordArray.sigBytes; words = words.slice(5, words.length); return new CryptoJS.lib.WordArray.init(words, sigBytes - 20); } /** function SplitWordArray(wordArray,startIndex,length){ var words = wordArray.words; var sigBytes = wordArray.sigBytes; var hexChars = []; for (var i = 0; i < sigBytes; i++) { var bite = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff; hexChars.push((bite >>> 4).toString(16)); hexChars.push((bite & 0x0f).toString(16)); } hexChars=hexChars.slice(startIndex,startIndex+length); return new CryptoJS.lib.WordArray.init(hexChars, length); } **/ function GetWordArray(value) { var displayFormat = $("#displayFormat").val(); var wrodArray = {}; switch (displayFormat) { case "Base64String": wrodArray = CryptoJS.enc.Base64.parse(value); break; case "BitString": wrodArray = CryptoJS.enc.Hex.parse(value); break; } return wrodArray; } function WrodArrayToString(wrodArray) { var displayFormat = $("#displayFormat").val(); var value = ""; switch (displayFormat) { case "Base64String": value = CryptoJS.enc.Base64.stringify(wrodArray); break; case "BitString": value = CryptoJS.enc.Hex.stringify(wrodArray); break; } return value; } </script> <style> h, div { margin: 10px 10px; } input[type=text] { width: 500px; } input[type=button] { margin: 0px 5px; padding: 10px; } select { width: 250px; } textarea { width: 500px; height: 150px; } </style> </head> <body> <div> <div> <h>HmacSha1 簽名</h> </div> <div> <label for="signtext">簽名</label> <br /> <input type="text" id="signtext" /> </div> <div> <label for="converttext">待處理文本:</label> <br /> <textarea id="converttext"></textarea> </div> <div> <label for="displayFormat">編碼格式:</label> <br /> <select id="displayFormat"> <option value="Base64String" selected="selected">Base64String</option> <option value="BitString">BitString</option> </select> </div> <div> <input type="button" value="簽名" id="buttonSign" /> <input type="button" value="驗證" id="buttonVerifySign" /> </div> <div> <label for="resulttext">結果:</label> <br /> <textarea id="resulttext"></textarea> </div> </div> </body> </html>
AES加密
加密
//AES加密 //plaintextWordArray 明文,一個CryptoJS.lib.WordArray對象 //keyWordArray 秘鑰,一個CryptoJS.lib.WordArray對象 //ivWordArray 偏移量,一個CryptoJS.lib.WordArray對象 //返回一個CryptoJS.lib.WordArray對象 function Encryptor(plaintextWordArray, keyWordArray, ivWordArray) { var encryptedData = undefined; //無偏移量加密 if (ivWordArray == null || ivWordArray == undefined) { encryptedData = CryptoJS.AES.encrypt(plaintextWordArray, keyWordArray, { mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.Pkcs7 }); } else { //有偏移量加密 encryptedData = CryptoJS.AES.encrypt(plaintextWordArray, keyWordArray, { iv: ivWordArray, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 }); } if (encryptedData!=null&&encryptedData != undefined) { return encryptedData.ciphertext; } return undefined; }
解密
// AES 解密 // ciphertextWordArray 密文,一個CryptoJS.lib.WordArray對象 // keyWordArray 秘鑰,一個CryptoJS.lib.WordArray對象 // ivWordArray 偏移量,一個CryptoJS.lib.WordArray對象 // 返回一個CryptoJS.lib.WordArray對象 function Decryptor(ciphertextWordArray, keyWordArray, ivWordArray) { var decryptedData = undefined; //密文必須為Base64格式的字符串 var ciphertext = ciphertextWordArray.toString(CryptoJS.enc.Base64); if (ivWordArray == null || ivWordArray == undefined) { decryptedData = CryptoJS.AES.decrypt(ciphertext, keyWordArray, { mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.Pkcs7 }); } else { decryptedData = CryptoJS.AES.decrypt(ciphertext, keyWordArray, { iv: ivWordArray, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 }); } return decryptedData; }
完整代碼

<html> <head> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js" type="text/javascript"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.9-1/crypto-js.min.js" type="text/javascript"></script> <!--<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.9-1/aes.js" type="text/javascript"></script>--> <script type="text/javascript"> //加密 var key = CryptoJS.enc.Base64.parse('5C9ErX8g1qLYA298clMcumQ+V9d46hQXZmJCVb7ZRUw='); var plaintext = '中文什么的也認識?'; plaintext = CryptoJS.enc.Utf8.parse(plaintext); var encryptedData = CryptoJS.AES.encrypt(plaintext, key, { mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.Pkcs7 }); var encryptedBase64Str = CryptoJS.enc.Base64.stringify(encryptedData.ciphertext); console.log(encryptedBase64Str); //解密 var decryptedData = CryptoJS.AES.decrypt(encryptedBase64Str, key, { mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.Pkcs7 }); var decryptedStr = decryptedData.toString(CryptoJS.enc.Utf8); console.log(decryptedStr); </script> <script type="text/javascript"> Math.randomByMaxValue = function (maxValue) { return parseInt(Math.random() * maxValue, 10); } </script> <script type="text/javascript"> $(function () { $("#buttonCreateKey").bind("click", function () { $("#Key").val(CreateKey()); }); $("#buttonCreateIv").bind("click", function () { $("#Iv").val(CreateIv()); }); $("#buttonEncryptor").bind("click", function () { var key = $("#Key").val(); var iv = $("#Iv").val(); var plaintext = $("#transferText").val(); if (key.length == 0) { showAlert("密鑰不能為空!"); return; } var plaintextWordArray = CryptoJS.enc.Utf8.parse(plaintext); var keyWordArray = CryptoJS.enc.Utf8.parse(key); var encryptedData = undefined; if (iv.length > 0) { var ivWordArray = CryptoJS.enc.Utf8.parse(iv); encryptedData = Encryptor(plaintextWordArray, keyWordArray, ivWordArray); } else { encryptedData = Encryptor(plaintextWordArray, keyWordArray, undefined); } if (encryptedData != null && encryptedData != undefined) { $("#resultText").val(WordArrayToString(encryptedData)); } else { $("#resultText").val('加密失敗!'); } }); $("#buttonDecryptor").bind("click", function () { var key = $("#Key").val(); var iv = $("#Iv").val(); var ciphertext = $("#transferText").val(); if (key.length == 0) { showAlert("密鑰不能為空!"); return; } var keyWordArray = CryptoJS.enc.Utf8.parse(key); var ciphertextWordArray = GetWordArray(ciphertext); var decryptorData = undefined; if (iv.length > 0) { var ivWordArray = CryptoJS.enc.Utf8.parse(iv); decryptorData = Decryptor(ciphertextWordArray, keyWordArray, ivWordArray); } else { decryptorData = Decryptor(ciphertextWordArray, keyWordArray, undefined); } if (decryptorData != null && decryptorData != undefined) { $("#resultText").val(CryptoJS.enc.Utf8.stringify(decryptorData)); } else { $("#resultText").val('解密失敗!'); } }); }); </script> <script type="text/javascript"> function GetWordArray(value) { var displayFormat = $("#displayFormat").val(); var WordArray = {}; switch (displayFormat) { case "Base64String": WordArray = CryptoJS.enc.Base64.parse(value); break; case "BitString": WordArray = CryptoJS.enc.Hex.parse(value); break; } return WordArray; } function WordArrayToString(wordArray) { var displayFormat = $("#displayFormat").val(); var value = ""; switch (displayFormat) { case "Base64String": value = CryptoJS.enc.Base64.stringify(wordArray); break; case "BitString": value = CryptoJS.enc.Hex.stringify(wordArray); break; } return value; } var constStr='ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'; function CreateKey() { var a = ''; for (var i = 0; i < 32; i++) { a += constStr[Math.randomByMaxValue(constStr.length)]; } return a; } function CreateIv() { var a = ''; for (var i = 0; i < 32; i++) { a += constStr[Math.randomByMaxValue(constStr.length)]; } return a; } function Encryptor(plaintextWordArray, keyWordArray, ivWordArray) { var encryptedData = undefined; if (ivWordArray == null || ivWordArray == undefined) { encryptedData = CryptoJS.AES.encrypt(plaintextWordArray, keyWordArray, { mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.Pkcs7 }); } else { encryptedData = CryptoJS.AES.encrypt(plaintextWordArray, keyWordArray, { iv: ivWordArray, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 }); } if (encryptedData!=null&&encryptedData != undefined) { return encryptedData.ciphertext; } return undefined; } function Decryptor(ciphertextWordArray, keyWordArray, ivWordArray) { var decryptedData = undefined; //密文必須為Base64格式的字符串 var ciphertext = ciphertextWordArray.toString(CryptoJS.enc.Base64); if (ivWordArray == null || ivWordArray == undefined) { decryptedData = CryptoJS.AES.decrypt(ciphertext, keyWordArray, { mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.Pkcs7 }); } else { decryptedData = CryptoJS.AES.decrypt(ciphertext, keyWordArray, { iv: ivWordArray, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 }); } return decryptedData; } function showAlert(message) { alert(message); } </script> <style> h, div { margin: 10px 10px; } input[type=text] { width: 500px; } input[type=button] { margin: 0px 5px; padding: 10px; } select { width: 250px; } textarea { width: 500px; height: 150px; } </style> </head> <body> <div> <h>AES 加密解密</h> <div> <label for="Key">秘鑰:</label> <br /> <input type="text" id="Key" /> </div> <div> <label for="Iv">偏移量:</label> <br /> <input type="text" id="Iv" /> </div> <div> <label for="displayFormat">顯示格式:</label> <br /> <select id="displayFormat"> <option value="Base64String" selected="selected">Base64String</option> <option value="BitString">BitString</option> </select> </div> <div> <label for="transferText">待處理文本:</label> <br /> <textarea id="transferText"></textarea> </div> <div> <input type="button" value="創建秘鑰" id="buttonCreateKey" /> <input type="button" value="創建偏移量" id="buttonCreateIv" /> <input type="button" value="加密" id="buttonEncryptor" /> <input type="button" value="解密" id="buttonDecryptor" /> </div> <div> <label for="resultText">結果:</label> <br /> <textarea id="resultText" readonly="readonly"></textarea> </div> </div> </body> </html>