无知者的无畏,从AES工具加密每次结果不一样引发的思考
因为大家的反馈实在是太热烈,我这边的速度跟不上大家的热情。但是大多数人的反馈都是友好并且积极的,直到我看到这一条反馈。
我的天,看到这个反馈我气得浑身发抖,大热天的全身冷汗手脚冰凉。我不知道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]
就是盐值,剩下的就是实际的密文。
进一步阅读源码可知,盐值是随机生成,不需要指定盐值。同时有一个密钥派生函数,根据输入的字符串派生出符合长度要求的密钥,所以即使用户输入的密钥长度不满足条件,也是可以正常加密的。
终于破案了!!!并不是在烧报纸,这里是为了代码的鲁棒性。
总结
恶语一句六月寒,良言一句三冬暖。不过这次能给大家带来知识的收获我也感到开心。
扫描关注公众号