轉載自作者:疾風劍豪灬
鏈接:https://blog.csdn.net/u011339397/article/details/104967488/
來源:簡書
可以實現前端加密,后端解密;后端加密,前端解密。代碼只是如何實現,而非原理。
效果
前端頁面HTML + JS
- 需要引入JS文件 —— CryptoJS
- GitHub:https://github.com/brix/crypto-js/releases,下載zip壓縮包解壓,修改文件夾名稱后引入項目即可
- API:https://cryptojs.gitbook.io/docs/
<!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <head> <meta name="viewport" content="width=device-width" /> <meta charset="UTF-8"/> <title>index</title> <script th:src="@{js/jquery.min.js}" type="text/javascript"></script> <script th:src="@{lib/crypto-js/crypto-js.js}" type="text/javascript"></script> <script th:src="@{lib/crypto-js/aes.js}" type="text/javascript"></script> <script th:inline="javascript"> var ctx = [[@{/}]]; </script> </head> <body> <div> 密碼:<input type="text" id="password"> <input type="button" id="pwSend" value="后端加密前端解密"/> <input type="button" id="encodeSend" value="前端加密后端解密"/> </div> <script> var key = 'ABCDEFGHIJKL_key'; var iv = "ABCDEFGHIJKLM_iv"; $(function () { $("#pwSend").click(function () { var password = $("#password").val(); postAjax("/encode", {password: password}, function (data) { console.log("后端加密,前端解密:") console.log("加密后:" + data); console.log("解密后:" + decrypt(data, key, iv)); }) }) $("#encodeSend").click(function () { var encryptStr = encrypt($("#password").val(), key, iv); postAjax("/decode", {encryptStr: encryptStr}, function (data) { console.log("前端加密,后端解密:") console.log("加密后:" + encryptStr); console.log("解密后:" + data); }) }) }) function postAjax(url, dataToPost, d, type, contentType, async) { url = (ctx + url).replace('//', '/'); $.ajax({ url: url, cache: false, async: async == undefined ? true : async, data: dataToPost, type: type == undefined ? "POST" : type, contentType: contentType == undefined ? 'application/x-www-form-urlencoded; charset=UTF-8' : contentType, success: function (data) { if (typeof d == "function") { d(data); } }, error: function (XMLHttpRequest, textStatus, errorThrown) { if (XMLHttpRequest.status == 403) { layer.msg("您沒有權限訪問,請聯系管理員!") } else if (XMLHttpRequest.status == 500) { layer.msg("服務器內部錯誤!") } else if (XMLHttpRequest.status == 404) { layer.msg("您訪問的內容不存在!") } else { layer.msg("服務器未知錯誤!") } } }); }; // 加密 function encrypt(code, key, iv) { var _code = CryptoJS.enc.Utf8.parse(code), _key = CryptoJS.enc.Utf8.parse(key), _iv = CryptoJS.enc.Utf8.parse(iv); var encrypted = CryptoJS.AES.encrypt(_code, _key, { iv: _iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 }); return encrypted.toString(); } // 解密 function decrypt(code, key, iv) { var _key = CryptoJS.enc.Utf8.parse(key), _iv = CryptoJS.enc.Utf8.parse(iv); var dec = CryptoJS.AES.decrypt(code, _key, { iv: _iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 }) var decStr = CryptoJS.enc.Utf8.stringify(dec); return decStr; } </script> </body> </html>
Controller
import com.lm.commons.utils.AESUtil; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.ResponseBody; @Controller public class TestController { @GetMapping({"/", "index"}) public String index() { return "index"; } @PostMapping("decode") @ResponseBody public String decode(String encryptStr) { try { String decryptStr = AESUtil.aesDecrypt(encryptStr); return decryptStr; } catch (Exception e) { e.printStackTrace(); return null; } } @PostMapping("encode") @ResponseBody public String encode(String password) { try { String encryptStr = AESUtil.aesEncrypt(password); return encryptStr; } catch (Exception e) { e.printStackTrace(); return null; } } }
AESUtil
import org.apache.commons.lang3.StringUtils; import sun.misc.BASE64Decoder; import sun.misc.BASE64Encoder; import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; public class AESUtil { //密鑰 (需要前端和后端保持一致)十六位作為密鑰 private static final String KEY = "ABCDEFGHIJKL_key"; //密鑰偏移量 (需要前端和后端保持一致)十六位作為密鑰偏移量 private static final String IV = "ABCDEFGHIJKLM_iv"; private static final String ALGORITHMSTR = "AES/CBC/PKCS5Padding"; // 算法/模式/補碼方式 /** * base 64 decode * @param base64Code 待解碼的base 64 code * @return 解碼后的byte[] * @throws Exception */ public static byte[] base64Decode(String base64Code) throws Exception{ return StringUtils.isEmpty(base64Code) ? null : new BASE64Decoder().decodeBuffer(base64Code); } /** * AES解密 * @param encryptBytes 待解密的byte[] * @return 解密后的String * @throws Exception */ public static String aesDecryptByBytes(byte[] encryptBytes) throws Exception { Cipher cipher = Cipher.getInstance(ALGORITHMSTR); byte[] temp = IV.getBytes("UTF-8"); IvParameterSpec iv = new IvParameterSpec(temp); cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(KEY.getBytes(), "AES"), iv); byte[] decryptBytes = cipher.doFinal(encryptBytes); return new String(decryptBytes); } /** * 將base 64 code AES解密 * @param encryptStr 待解密的base 64 code * @return 解密后的string * @throws Exception */ public static String aesDecrypt(String encryptStr) throws Exception { return StringUtils.isEmpty(encryptStr) ? null : aesDecryptByBytes(base64Decode(encryptStr)); } /** * base 64 decode * @param encryptedByte * @return 編碼后的string */ public static String base64Encode(byte[] encryptedByte) { return new BASE64Encoder().encodeBuffer(encryptedByte); } /** * AES解密 * @param code 待加密的string * @return 加密並 * @throws Exception */ public static String aesEncrypt(String code) throws Exception { Cipher cipher = Cipher.getInstance(ALGORITHMSTR); byte[] temp = IV.getBytes("UTF-8"); IvParameterSpec iv = new IvParameterSpec(temp); cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(KEY.getBytes(), "AES"), iv); byte[] encryptBytes = cipher.doFinal(code.getBytes()); return base64Encode(encryptBytes); // 編碼,再次加密 } //測試一下 public static void main(String[] args) throws Exception { String str = "AzPbSRRVk2f7EHwbSw/reg=="; String password = "admin123456"; System.out.println(aesEncrypt(password)); System.out.println(aesDecrypt(str)); } }