从Node.js加密后,解密Python中的AES-256-CTR有效负载 [英] Decrypt AES-256-CTR payloads in Python when encrypted from Nodejs

查看:294
本文介绍了从Node.js加密后,解密Python中的AES-256-CTR有效负载的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在Node.js中编写了一个使用AES-256-CTR加密用户密码的应用程序:

  const crypto = require(' crypto')
const masterkey ='azertyuiopazertyuiopazertyuiopaz'
const cipher = crypto.createCipher('aes-256-ctr',masterkey)
console.log(cipher.update('antoine', 'utf8','hex')+ cipher.final('hex'))// => 6415bc70ad76c6

然后将其持久保存到数据库中,现在我正尝试从Python脚本中解密它像这样使用PyCrypto:

  masterkey ='azertyuiopazertyuiopazertyuiopaz'
密码='6415bc70ad76c6'

从Crypto.Cipher导入AES
导入os
导入binascii
counter = os.urandom(16)
#counter = bytes(16)#不起作用
#counter = masterkey [0:16] .encode()#不起作用
cipher = AES.new(masterkey,AES.MODE_CTR,counter = lambda:counter)
print(cipher.decrypt(binascii .a2b_hex(password)))

但这在这里给了我完全错误的结果。



你知道我在想什么吗?



编辑



感谢zaph,看来我的Javascript代码加密数据的方式是不安全的。我仍然必须弄清楚Node内部正在使用什么IV。我已经尝试了很多没有成功的

  masterkey [0:16] .encode()
bytes(16)


解决方案

根据问题中的新信息进行更新:最佳选择是Nodejs使用默认计数器值。



加密和解密必须使用相同的计数器值。但是加密时没有提供计数器值,解密时使用了随机值,因此它永远无法工作。



使用: crypto.createCipheriv(algorithm ,键,iv),其中 iv 是随机计数器的初始值。



它必须在加密时创建一个随机计数器值并将其保存,以便可以在解密时使用相同的初始计数器值。一种选择是在加密数据前加上计数器值,它不必是秘密的。然后在解密时就可以从加密的数据中分离出来并使用它。



此外,在使用CTR模式时,绝不能再使用相同的密钥来使用相同的初始计数器值。 / p>

请参见 CTR模式


PyCrypto文档 CTR模式



MODE_CBC

密码块链接(CBC)。每个密文块取决于当前和所有先前的明文块。 需要初始化向量(IV)



IV是要发送到接收器的数据块。 IV可以公开,但是必须由接收方进行身份验证,并且应该随机选择。)


IV是初始计数器值。


[Nodejs dociumewnrtation:类:密码




  crypto。 createCipheriv(algorithm,key,iv)
算法< string>
键< string> | < Buffer> | < TypedArray> | < DataView>
iv< string> | < Buffer> | < TypedArray> | < DataView>




使用给定的算法,密钥和初始化向量(iv)。



I wrote an application in Nodejs that encrypts user passwords using AES-256-CTR :

const crypto = require('crypto')
const masterkey = 'azertyuiopazertyuiopazertyuiopaz'
const cipher = crypto.createCipher('aes-256-ctr', masterkey)
console.log(cipher.update('antoine', 'utf8', 'hex') + cipher.final('hex')) //=> 6415bc70ad76c6

It then gets persisted into a database and now I'm trying to decipher it from a Python script using PyCrypto like this :

masterkey = 'azertyuiopazertyuiopazertyuiopaz'
password = '6415bc70ad76c6'

from Crypto.Cipher import AES
import os
import binascii
counter = os.urandom(16)
# counter = bytes(16) # does not work
# counter = masterkey[0:16].encode() # does not work
cipher = AES.new(masterkey, AES.MODE_CTR, counter=lambda: counter)
print(cipher.decrypt(binascii.a2b_hex(password)))

But it gives me completely wrong results here.

Do you know what I am missing ?

EDIT

Thanks to zaph, it appears that the way my Javascript code encrypts data is insecure. I still have to figure out what IV is being used internally by Node. I've tried many without success

masterkey[0:16].encode()
bytes(16)

解决方案

Update based on new information in the question: The best bet is that Nodejs is using a default counter value.

The same counter value must be used for both encryption and decryption. But no counter value is provided on encryption and a random value is used on decryption so it can never work.

Use: crypto.createCipheriv(algorithm, key, iv) where iv is the random counter initial value.

It is necessary to create a random counter value on encryption and save it so that the same initial counter value can be used on decryption. One option is to prefix the encrypted data with the counter value, it does not need to be secret. Then on decryption it can be split from the encrypted data and used.

Also when using CTR mode the same initial counter value must never be use again with the same key.

See CTR mode

PyCrypto documentation CTR mode:

MODE_CBC
Cipher-Block Chaining (CBC). Each of the ciphertext blocks depends on the current and all previous plaintext blocks. An Initialization Vector (IV) is required.

The IV is a data block to be transmitted to the receiver. The IV can be made public, but it must be authenticated by the receiver and it should be picked randomly.)

The IV is the initial counter value.

[Nodejs dociumewnrtation: Class: Cipher:

crypto.createCipheriv(algorithm, key, iv)
    algorithm <string>  
    key <string> | <Buffer> | <TypedArray> | <DataView>
    iv <string> | <Buffer> | <TypedArray> | <DataView>

Creates and returns a Cipher object, with the given algorithm, key and initialization vector (iv).

这篇关于从Node.js加密后,解密Python中的AES-256-CTR有效负载的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆