1. 程式人生 > 實用技巧 >前後端AES加密,CBC模式:偏移量加密

前後端AES加密,CBC模式:偏移量加密

轉載自作者:疾風劍豪灬
連結:https://blog.csdn.net/u011339397/article/details/104967488/
來源:簡書

可以實現前端加密,後端解密;後端加密,前端解密。程式碼只是如何實現,而非原理。

效果

前端頁面HTML + JS

<!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));
    }

}