一尘不染

Node.js中的AES加密以匹配Python中预期的解密

node.js

我有以下用于解密的Python脚本:

from Crypto.Cipher import AES

shared_secret = raw_input('Enter crypted_shared_secret: ').strip()
cipher = AES.new(shared_secret.decode('base64'), AES.MODE_ECB)

blob = raw_input('Enter crypted_blob: ').strip()
plain = cipher.decrypt(blob.decode('base64'))

print(plain)

我正在尝试blob使用Node 生成使用该脚本生成原始值的值。这是我的尝试:

const Crypto = require('crypto');

var shared_secret = Crypto.randomBytes(32);
var cipher = Crypto.createCipher('aes-256-ecb', shared_secret);
crypted_blob = cipher.update(blob, 'utf8', 'base64') + cipher.final('base64');

我只能修改Node.js脚本,但是我不确定它出了什么问题。


阅读 221

收藏
2020-07-07

共1个答案

一尘不染

将共享密钥用于加密 ,才需要将其编码为Base64 :

var shared_secret = Crypto.randomBytes(32);
var cipher = Crypto.createCipheriv('aes-256-ecb', shared_secret, "");
crypted_blob = cipher.update(blob, 'utf8', 'base64') + cipher.final('base64');
// send `shared_secret.toString('base64')`

其他问题:

  • crypto.createCipher 假定共享机密是密码而不是密钥,这就是为什么它将使用错误的密钥派生(与OpenSSL兼容)的原因。
  • Node.js的加密模块会自动应用PKCS#7填充(与PKCS#5填充相同),但是PyCrypto不会自行应用任何填充。因此,您要么需要在Python中使用相同的取消填充,要么可以使用来禁用node.js中的填充Cipher.setAutoPadding(false);,但是随后您将必须提供块大小倍数(AES为16字节)的纯文本。

安全注意事项:

  • 切勿使用 ECB模式。它是确定性的,因此在语义上不安全。您至少应使用CBCCTR之类的随机模式。最好对您的密文进行身份验证,这样就不可能进行像填充预言攻击之类的攻击。这可以通过GCM或EAX之类的经过身份验证的模式来完成,也可以通过“ 加密-然后-MAC”方案来完成。
2020-07-07