【问题标题】:NodeJS AES encrypt Python decryptNodeJS AES 加密 Python 解密
【发布时间】:2019-11-04 06:26:55
【问题描述】:

我有一个 nodejs 服务,它对一些需要在 Python 中解密的数据使用 AES 加密。 无论我做什么,我都无法让它发挥作用。 NodeJS 代码:

const algorithm = 'aes-128-ctr';

function encryptScript(data, key) {
    const cipher = crypto.createCipher(algorithm, key);

    let crypted = cipher.update(data, 'utf8', 'hex');
    crypted += cipher.final('hex');

    return crypted;
}

我已经在 Python 中尝试过:

counter = Counter.new(128)
cipher = AES.new(key, AES.MODE_CTR, counter=counter)
print cipher.decrypt(enc.decode("hex"))

但它不起作用。

我的第一个问题是 Python 代码不接受长度超过 32 字节的密钥(Nodejs 代码可以)。

如果我使用 NodeJS 加密模块,则解密工作正常:

function decryptScript(data, key) {
    const decipher = crypto.createDecipher(algorithm, key);
    let dec = decipher.update(data, 'hex', 'utf8');
    dec += decipher.final('utf8');
    return dec;
}

我不知道节点在做什么,但它可能与数据的一些填充有关。

我怎样才能让它工作?

(我更喜欢不需要更改 NodeJS 代码而只需要更改 Python 脚本的解决方案)。

【问题讨论】:

    标签: python node.js encryption aes


    【解决方案1】:
    • CreateCipher 使用EVP_BytesToKey 从密码创建一个密钥和一个 IV(在 NodeJS 代码中称为 key 实际上是 password) . Here 是 Python 中 EVP_BytesToKey 的实现。要使用的参数在CreateCipher的文档中有描述:MD5,无盐,一次迭代。在CTR-mode 中,IV 通常随着每个块以要定义的值开始而递增。 CreateCipher 使用 EVP_BytesToKey 确定的 IV 作为起始值。因此,CreateCipher 的功能可以在 Python 中实现如下:

      import hashlib
      from Crypto.Cipher import AES
      from Crypto.Util import Counter
      
      ...
      
      encrypted = '5e99b5190f12143c057f6bdd8625f958682e737c11e138a2f571c050313dbe1008347604c7c7e8bf506a0a'   # Example
      
      # Generate key and iv
      keySize = 16
      ivSize = 16
      digest = hashlib.md5
      salt = b''
      password = b'123456'                                                                                   # Example
      iteration = 1
      keyiv = EVP_BytesToKey(keySize, ivSize, digest, salt, password, iteration)
      key = keyiv[0]
      iv = keyiv[1]
      
      # Define counter
      nbits = 128
      initial_value = int.from_bytes(iv, byteorder = 'big');
      counter = Counter.new(nbits, initial_value = initial_value)
      
      # Decrypt
      cipher = AES.new(key, AES.MODE_CTR, counter = counter)
      decrypted = cipher.decrypt(bytes.fromhex(encrypted))
      print("Decrypted: " + decrypted.decode('utf8'))
      

      密文是通过 NodeJS 代码使用以下输入生成的:

      key = '123456';
      data = 'The quick brown fox jumps over the lazy dog';
      
    • 请注意,CreateCipher 已弃用,不应再使用,尤其是不能与 CTR 模式结合使用。而是可以使用 CreateCipheriv。在 CTR 模式中,重要的是密钥/IV 对只使用一次。否则将失去安全性,请参阅hereCreateCipher 不提供随机化,即相同的密码始终生成相同的密钥和 IV,因此始终生成相同的密钥流。因此,如果多次使用相同的密码,就会失去安全性。另一方面,CreateCipheriv 需要一个密钥和一个随机 IV。这里可以有一个键 使用多次,只要 IV 的随机化确保键/值对不重复,请参阅 here

    【讨论】:

    • 非常感谢您的出色解释,对 Python2 进行了一些小的调整,它可以完美运行。我知道不应该使用CreateCipher,但这只是一个小任务。
    • @AmirRossert 您能否告诉我们您为使其在 python3 上运行所做的更改?当我运行“decrypted.decode('utf8')”时,我遇到了这个错误“'utf-8' codec can't decode byte 0xe4 in position 1: invalid continuation byte”,所以我想我有一个某处的小错误
    猜你喜欢
    • 1970-01-01
    • 2019-10-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-24
    • 2018-08-16
    • 2021-01-05
    • 2018-11-28
    相关资源
    最近更新 更多