js AES-128-CBC 解密易班轻应用verify_request

Posted lzyuid

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了js AES-128-CBC 解密易班轻应用verify_request相关的知识,希望对你有一定的参考价值。

易班文档

易班轻应用框架服务通过get方式在易班客户端webview或浏览器重定向加载应用实际地址,以提供给应用用户授权状态和基本信息数据, 请避免应用实际地址使用自带get参数。加密字符串使用了AES-128-CBC对称加密算法,其中应用的AppSecret为解密的密钥,AppID为向量。 原32字符长度appID应用依旧采用AES-256-CBC对称加密算法。

使用CryptoJS进行解密,CryptoJS解密base64格式的密文,返回的verify_request为16进制格式的,所以要将16进制转为base64格式,加密方法为AES-128-CBC,填充ZeroPadding
技术图片

function decrypted(data) {

            var padding = '0000000000000000000';
            var temp_key = AppSecret;
            var temp_iv =AppID;
     
            var key = CryptoJS.enc.Latin1.parse(temp_key.substring(0, 32));
            var iv = CryptoJS.enc.Latin1.parse(temp_iv.substring(0, 16));



            var decrypted = CryptoJS.AES.decrypt(sha1_to_base64(data), key, { iv: iv, padding: CryptoJS.pad.ZeroPadding });
            var decodeData = decrypted.toString(CryptoJS.enc.Utf8);
            return JSON.parse(decodeData);
        }
        
        function sha1_to_base64(sha1) {
            var digits = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
            var base64_rep = "";
            var cnt = 0;
            var bit_arr = 0;
            var bit_num = 0;

            for (var n = 0; n < sha1.length; ++n) {
                if (sha1[n] >= 'A' && sha1[n] <= 'Z') {
                    ascv = sha1.charCodeAt(n) - 55;
                }
                else if (sha1[n] >= 'a' && sha1[n] <= 'z') {
                    ascv = sha1.charCodeAt(n) - 87;
                }
                else {
                    ascv = sha1.charCodeAt(n) - 48;
                }

                bit_arr = (bit_arr << 4) | ascv;
                bit_num += 4;
                if (bit_num >= 6) {
                    bit_num -= 6;

                    base64_rep += digits[bit_arr >>> bit_num];
                    bit_arr &= ~(-1 << bit_num);
                }
            }

            if (bit_num > 0) {
                bit_arr <<= 6 - bit_num;
                base64_rep += digits[bit_arr];
            }
            var padding = base64_rep.length % 4;

            if (padding > 0) {
                for (var n = 0; n < 4 - padding; ++n) {
                    base64_rep += "=";
                }
            }
            return base64_rep;
        }

完整代码

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script src="crypto-js-develop/src/core.js"></script>
    <script src="crypto-js-develop/src/lib-typedarrays.js"></script>
    <script src="crypto-js-develop/src/x64-core.js"></script>
    <script src="crypto-js-develop/src/enc-utf16.js"></script>
    <script src="crypto-js-develop/src/enc-base64.js"></script>
    <script src="crypto-js-develop/src/cipher-core.js"></script>
    <script src="crypto-js-develop/src/pad-zeropadding.js"></script>
    <script src="crypto-js-develop/src/aes.js"></script>
    <script src="js/jquery.min.js">s</script>
</head>

<body>
    <h1>hello</h1>
    <script>
        var AppSecret = '916501e0cdd6f328037951782b9198e6';
        var AppID = 'd1b0b42e31d73e87';
        var url = 'http://f.yiban.cn/iapp596252';

        var data = getQueryVariable("verify_request");
        data = "54fd38e93dcc0aeb9cf08ecb8eec6d8667db09e94450afc49e0b456c0b72602731ec3aebef83652031e624251f888170c31036d68eeee54dc82afb2ae7befd4f540a4c8126afb6f8a56fd30a8efe13b7";
        var res = decrypted(data);
        console.log(res);
        
        document.write(JSON.stringify(res))

        // if (!res['visit_oauth']) {
        //     //跳转授权
        //     window.location.href = "https://oauth.yiban.cn/code/html?client_id="+AppID+"&redirect_uri="+url;
        // } else {

        //     document.write("<br>access_token:")
        //     document.write(res['visit_oauth']['access_token']);
        //     var access_token = res['visit_oauth']['access_token'];
        //     $.get("/api/user/me?access_token=" + access_token, function (data, status) {
        //         alert("Data: " + data + "nStatus: " + status);
        //     });
        // }
        function getQueryVariable(variable) {
            var query = window.location.search.substring(1);
            var vars = query.split("&");
            for (var i = 0; i < vars.length; i++) {
                var pair = vars[i].split("=");
                if (pair[0] == variable) { return pair[1]; }
            }
            return (false);
        }
        function decrypted(data) {

            var padding = '0000000000000000000';
            var temp_key = AppSecret;
            var temp_iv =AppID;
     
            var key = CryptoJS.enc.Latin1.parse(temp_key.substring(0, 32));
            var iv = CryptoJS.enc.Latin1.parse(temp_iv.substring(0, 16));



            var decrypted = CryptoJS.AES.decrypt(sha1_to_base64(data), key, { iv: iv, padding: CryptoJS.pad.ZeroPadding });
            var decodeData = decrypted.toString(CryptoJS.enc.Utf8);
            return JSON.parse(decodeData);
        }
        
        function sha1_to_base64(sha1) {
            var digits = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
            var base64_rep = "";
            var cnt = 0;
            var bit_arr = 0;
            var bit_num = 0;

            for (var n = 0; n < sha1.length; ++n) {
                if (sha1[n] >= 'A' && sha1[n] <= 'Z') {
                    ascv = sha1.charCodeAt(n) - 55;
                }
                else if (sha1[n] >= 'a' && sha1[n] <= 'z') {
                    ascv = sha1.charCodeAt(n) - 87;
                }
                else {
                    ascv = sha1.charCodeAt(n) - 48;
                }

                bit_arr = (bit_arr << 4) | ascv;
                bit_num += 4;
                if (bit_num >= 6) {
                    bit_num -= 6;

                    base64_rep += digits[bit_arr >>> bit_num];
                    bit_arr &= ~(-1 << bit_num);
                }
            }

            if (bit_num > 0) {
                bit_arr <<= 6 - bit_num;
                base64_rep += digits[bit_arr];
            }
            var padding = base64_rep.length % 4;

            if (padding > 0) {
                for (var n = 0; n < 4 - padding; ++n) {
                    base64_rep += "=";
                }
            }
            return base64_rep;
        }


    </script>
</body>

</html>

参考

JS:十六进制字符串转为base64

https://blog.csdn.net/herongoal/article/details/81137895

ase在线解密

http://ctf.ssleye.com/caes.html

CryptoJS

https://github.com/sytelus/CryptoJS

以上是关于js AES-128-CBC 解密易班轻应用verify_request的主要内容,如果未能解决你的问题,请参考以下文章

AES (aes-cbc-128, aes-cbc-192, aes-cbc-256) 使用 openssl C 加密/解密

Python中的AES-128 CBC解密

nodejs中aes-128-cbc加密和解密

js中怎么使用AES-128-CBC加密

微信AES-128-CBC加密解密

nodejs和java交互 AES-128-CBC加密解密