AES256加密在node.js和objective-c中获取的结果不同

5

1.Node.js

    var crypto = require('crypto');
    var key = "my password";
    var text = "text to encrypt";  
    var cipher = crypto.createCipher('aes-256-cbc',key);  
    var crypted =cipher.update(text,'utf8','base64');
    crypted+=cipher.final('base64');

结果: ZeYCYOrR/w7qSAZVYht8+Q==

2. Objective-C

{
    NSString *key = @"my password";
    NSString *text = @"text to encrypt";
    NSData *plain = [secret dataUsingEncoding:NSUTF8StringEncoding];
    NSData *cipher = [plain AES256EncryptWithKey:key];
    NSLog(@"%@\n", [cipher base64Encoding] );
}

结果: raFGdTWYvSPWpkgtF9LJIg==

[AES256EncryptWithKey:]在此处链接


2
我的猜测是node.js正在自动生成IV值,而iOS正在使用全零向量。尝试为两者指定相同的IV值(文档表明node.js方法也将接受IV)。 - borrrden
@borrrden,有一个方法crypto.createCipheriv(algorithm, key, iv),我应该如何设置iv? - Mil0R3
它只是一个128位长的二进制字符串,你可以选择任何你想要的,只需要在两边使用相同的即可。 - borrrden
实际上,我认为你需要先将 Node.js 中的字符串转换为二进制,就像在 Objective-C 版本中所做的那样,但我不确定如何操作(对 Node 不熟悉)。 - borrrden
我执行了你的Node.js代码,得到了不同的结果。这是使用给定的密钥和文本产生的结果,还是你的生产代码的结果? - tomekK
@tomekK 这里是密钥和文本:var key = "我的密码"; var text = "要加密的文本"; - Mil0R3
1个回答

1
问题在于node.js crypto.createCipher 内部使用一个密钥派生函数 EVP_BytesToKey()key = "my password" 生成 AES 密钥和 iv。因此,node.js 和 Common Crypto 的实际 AES 密钥是不同的。
答案是使用 crypto.createCipheriv(algorithm, key, iv) 替换 crypto.createCipher(algorithm, password)
根据 node.js 文档:

为了遵循 OpenSSL 推荐使用 pbkdf2 而不是 EVP_BytesToKey,建议您使用 crypto.pbkdf2 派生密钥和 iv,然后使用 createCipheriv() 创建密码流。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接