记一次AES密文解码之CryptJS能行其他算法不行的悲伤经历

事情缘起

放假闲来无事,在某网站上看到其前端与后端的HTTPS通信,表单数据都进行了加密,搞得蛮像那么回事,于是F12查看网络请求,发现接收的数据使用CryptoJS进行了加密,其解密时使用了如下的代码段:

o = l.a[O("0x1e", "jHr#")][O("0x1f", "9Abd")](l.a[O("0x20", "WKV&")][O("0x21", "q^PV")].create({
                            ciphertext: l.a[O("0x22", "WKV&")][O("0x23", "6PiS")][O("0x24", "KOgJ")](n)
                        }), l.a[O("0x25", "u)^x")1]
						[O("0x26", "3y6f")][O("0x27", "u)^x")](e), {
                            mode: l.a[O("0x28", "*z#I")][O("0x29", "6bNr")],
                            padding: l.a[O("0x2a", "ZjZb")][O("0x2b", "9Abd")]
                        })[O("0x2c", "bQUb")](l.a[O("0x2d", "cd6[")][O("0x2e", "*)*G")])
                          , r = void 0;

还原加密混淆后的js代码

对其进行DEBUG,这代码根本没法读,显示是经过了混淆处理的。只能手动的一行行的将他翻译过来。
通过添加表达式监控,其映射关系如下:

O("0x1e", "jHr#")==AES
O("0x1f", "9Abd")==decrypt
O("0x20", "WKV&")==lib
O("0x21", "q^PV")="CipherParams"
O("0x22", "WKV&")==enc
O("0x23", "6PiS")]==Hex
O("0x24", "KOgJ")==parse
O("0x25", "u)^x")==enc
O("0x26", "3y6f")==Hex,
O("0x27", "u)^x")==parse
O("0x28", "*z#I")==mode
O("0x29", "6bNr")==ECB
O("0x2a", "ZjZb")==pad
O("0x2b", "9Abd")="Pkcs7"
O("0x2a", "ZjZb")==pad
O("0x2b", "9Abd")=="Pkcs7"
O("0x2c", "bQUb")==toString
O("0x2d", "cd6[")==enc
O("0x2e", "*)*G")=="Utf8"
O("0x2f", "yT!v")==parse

对应到代码,翻译过来结果如下:

l.a.AES.decrypt(l.a.lib.CipherParams.create({ciphertext:l.a.enc.Hex.parse(n)}),
l.a.enc.Hex.parse(e),
{mode: l.a.mode.ECB,padding:l.a.pad.Pkcs7})
.toString(l.a.enc.Utf8)

其中l.a显示就是CryptoJS对象,再翻译一下,代码长这个样子

其实它长这个样子,很正经的

CryptoJS.AES.decrypt(
		CryptoJS.lib.CipherParams.create({ciphertext:CryptoJS.enc.Hex.parse(n)}),
		CryptoJS.enc.Hex.parse(e), {
		mode: CryptoJS.mode.ECB,  // 加密模式
        padding: CryptoJS.pad.Pkcs7,  // 填充方式
    }).toString(CryptoJS.enc.Utf8);

这个就是一段很正经的CryptoJs的AES解密代码,key是CryptoJS.enc.Hex.parse(e)
而e和n的值都可以通过控制台获取到。

e = "aLorRqjfhaj0cwgqZfUJdvqACF31tEdV";
n="754d9212905f57839ef8378f98dcde2f7c1dc7ae008584644edf33da7229714e81c90d628621fa35f5152479ba94d4d5e7dc27821a0d3e6a8085a561ea3907987c81aa83a81fb85ca616f40e5a993fa1fb7a980c72841775c6d338c414b85567e8e2fea170a2d6e38d20f34da21e1f4c0769a37813e2362b9be057d997f52cdd97104ab7aab3fcea7ca16811734d3e0da8fdfcdf5dd41c84847ebd62bb38a86d3818ac6005171d7fc45e814bd9e51baeb5075e9fa1fb469952ba01345c9c31ff8dd00deeeba94795d9e7b6e877948d178d1e961108d40bded7a48c1b264c4567c9a544061ec8191318c9407b78d1c480c00cbba96949b4a452de68842630c6051b5c35d29a98fd4933ad68e72cdfc5a95b3a0928773fcf4757211ca56d8ee4f97cf7a57eaefc4263a6392516b137620c5ceab37f98ac1c66d020de3172a0c8fefb08931479c47a48a14a51f9c93ca960871ea49e8b468f646805adf85f16df289313bfe713e8725163142aaaa658c8392e9a982130b60370739f086fdc161c6588f80123c66ef1dbe0cbf506f3ea444de1cb22f0d51fd0bd99f0dba215d9640ceba04dc94f121e3e4fc1920f2a734cb1";
var decryptedData = CryptoJS.AES.decrypt(
		CryptoJS.lib.CipherParams.create({ciphertext:CryptoJS.enc.Hex.parse(n)}),
		CryptoJS.enc.Hex.parse(e), {
		mode: CryptoJS.mode.ECB,  // 加密模式
        padding: CryptoJS.pad.Pkcs7,  // 填充方式
    }).toString(CryptoJS.enc.Utf8);
console.log("解密结果", decryptedData)

这段代码可以正常运行,解密的结果如下:

{
“context”: {},
“entities”: {
“ttsProgress”: 100,
“file”: {
“name”: “p12wb20220405.mp3”,
“url”: “https://file.peiyinshenqi.club/audio/p12wb20220405.mp3”,
“urlHttps”: “https://file.peiyinshenqi.club/audio/p12wb20220405.mp3”
},
“mp3Duration”: {
“value”: 6,
“text”: “00:06”
},
“showAddToCollect”: true,
“ad”: {
“show”: true,
“src”: “http://cdn.peiyinshenqi.club/publicPost/share-coin-guide.png”,
“type”: “page”,
“page”: “…/…/pages/shareMoney/shareMoney”
}
}
}

JAVA中无法解密一度让我怀疑人生

将这个解密代码写成java方法,却总是报错,让我很崩溃。让人更气的是。java代码长这样

private static String AES_KEY = "aLorRqjfhaj0cwgqZfUJdvqACF31tEdV";

    /**
     * PKCS5Padding -- Pkcs7 两种padding方法都可以
     * @param content  16进制
     * @return
     */
    public static String decryptHex(String content) {
        try {
            SecretKeySpec skeySpec = new SecretKeySpec(AES_KEY.getBytes("UTF-8"), "AES");
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS7Padding"); // "算法/模式/补码方式"
            cipher.init(Cipher.DECRYPT_MODE, skeySpec);
            return new String(cipher.doFinal(Hex.decodeHex(content.toCharArray())));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

通过CryptoJS写一段加密代码,将生产的密文用上面代码来解密,却可以:

var key = 'aLorRqjfhaj0cwgqZfUJdvqACF31tEdV';
var mingwen = "我买了个表。真实的蛋疼。";
	let myEncrypt1 = CryptoJS.AES.encrypt(mingwen, Key, {
		mode: CryptoJS.mode.ECB,
		padding: CryptoJS.pad.Pkcs7
	}).ciphertext.toString();
	console.log("biao=", myEncrypt1);
	// 打印结果:biao= 131fff7d9cdc61f2891bc039d49a4831c7f0e52ff789eb318962da398c6722004caba771c895affe06a510b8b105e07e

将字符串放到java中去解密

String encrypted = "131fff7d9cdc61f2891bc039d49a4831c7f0e52ff789eb318962da398c6722004caba771c895affe06a510b8b105e07e";
System.out.println("解密:"+ decryptHex(encrypted));

// 输出结果:解密:我买了个表。真实的蛋疼。

继续将这个加密字符用CryptoJS来进行解密:

var mykey = "aLorRqjfhaj0cwgqZfUJdvqACF31tEdV";
var key = CryptoJS.enc.Utf8.parse(mykey );
var encryptedStr = "131fff7d9cdc61f2891bc039d49a4831c7f0e52ff789eb318962da398c6722004caba771c895affe06a510b8b105e07e";
var decryptedData = CryptoJS.AES.decrypt(
		CryptoJS.lib.CipherParams.create({ciphertext:CryptoJS.enc.Hex.parse(encryptedStr)}),
		key, {
		mode: CryptoJS.mode.ECB,  // 加密模式
        padding: CryptoJS.pad.Pkcs7,  // 填充方式
    }).toString(CryptoJS.enc.Utf8);
console.log("解密结果", decryptedData)
// 解密结果 我买了个表。真实的蛋疼。

看看别人能不能解析

也就是说用JAVA加密后的字符串,使用CryptoJs可以正常的解密。而用CryptoJs能解密的密文,JAVA却不一定能。为了证明不是我自身的原因,我找了几个在线解密AES的网站,其中许多网站都很水,参数都不能配置,广告还贼多。比较靠谱的是这个
SSL在线工具
看看结果怎么样:
解密没有问题
在试试某网站的加密字符串
boss也无能为力

心累,走了

这样我就放心了。说明CryptoJs很强大呢,还是xx网站行车不规范呢?
本次探索到此为止,加密解密这些算法比较专业,咱也无力去深入研究。也许是我这个java代码抄的有点问题,也许是这个在线解密网站代码有问题吧。迷雾重重,你能找到原因吗?

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值