无知者的无畏,从AES工具加密每次结果不一样引发的思考

2023-12-30
758

因为大家的反馈实在是太热烈,我这边的速度跟不上大家的热情。但是大多数人的反馈都是友好并且积极的,直到我看到这一条反馈。

我的天,看到这个反馈我气得浑身发抖,大热天的全身冷汗手脚冰凉。我不知道36度的嘴是如何说出这么冰冷的话语的。我免费开发功能,方便大家。在你看来居然是在给你烧纸?!!!

有的时候多动动脑子或者百度一下也是一种进步的方式。

不多说,让我们实践一把,先打开:AES加密  上图

可以看到的确加密结果是不一样的,但是都可以解密出来。是不是很神奇?!这是为什么呢?

虽然每次加密结果不一致,但开头的一段数据总是 U2FsdGVkX1,于是先解 base64 查看有没有可读的内容。

密文总是以 Salted__开头。

在源码面前没有秘密。我们来看看这个功能是怎么实现的。

本功能是用的js的crypto-js

https://static.wetools.com/assets/src/js/lib/crypto-js/cipher-core.js

在 646 行左右,parse 函数的作用是解析出实际密文和 salt 值。

parse: function (openSSLStr) {
	            // Parse base64
	            var ciphertext = Base64.parse(openSSLStr);

	            // Shortcut
	            var ciphertextWords = ciphertext.words;

	            // Test for salt
	            if (ciphertextWords[0] == 0x53616c74 && ciphertextWords[1] == 0x65645f5f) {
	                // Extract salt
	                var salt = WordArray.create(ciphertextWords.slice(2, 4));

	                // Remove salt from ciphertext
	                ciphertextWords.splice(0, 4);
	                ciphertext.sigBytes -= 16;
	            }

	            return CipherParams.create({ ciphertext: ciphertext, salt: salt });
	        }

以 word(一个 word 是 8 个 16 进制,就是 32 个 bit,4 个字节)为单位将原密文分割为数组,ciphertextWords[0]0x53616c74(Salt),ciphertextWords[1]0x65645f5f(ed__),ciphertextWords[2]ciphertextWords[3]就是盐值,剩下的就是实际的密文。

进一步阅读源码可知,盐值是随机生成,不需要指定盐值。同时有一个密钥派生函数,根据输入的字符串派生出符合长度要求的密钥,所以即使用户输入的密钥长度不满足条件,也是可以正常加密的。

终于破案了!!!并不是在烧报纸,这里是为了代码的鲁棒性。

总结

恶语一句六月寒,良言一句三冬暖。不过这次能给大家带来知识的收获我也感到开心。

转载时必须以链接形式注明原始出处及本声明

扫描关注公众号