前后端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));
    }

}

 

posted @ 2020-10-13 17:28  忘忧山的兰木  阅读(2729)  评论(0编辑  收藏  举报
她只是想吃这个而已啊……这一定是她非常爱吃的,我居然连如此细微的幸福也夺走了……
Hide
Switch
Save