使用openssl和PyCrypto进行AES_128_CTR加密 [英] AES_128_CTR encryption by openssl and PyCrypto

查看:170
本文介绍了使用openssl和PyCrypto进行AES_128_CTR加密的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

想知道通过openssl将AES_128_CTR加密转换为PyCrypto的正确方法.

Wondering the right way to convert a AES_128_CTR encryption by openssl to PyCrypto.

首先,我通过openssl进行了如下加密:

First, I did an encryption by openssl as following:

openssl enc -aes-128-ctr -in input.mp4 -out output.openssl.mp4 -K 7842f0a1ebc38f44e3e0c81943f68582 -iv d01f40dfc8ec8cd9

然后,我尝试通过PyCrypto做同样的事情:

And then, I tried to do the same thing through PyCrypto:

from Crypto.Cipher import AES
from Crypto.Util import Counter
key = '7842f0a1ebc38f44e3e0c81943f68582'
iv = 'd01f40dfc8ec8cd9'

ctr_e = Counter.new(128, initial_value=int(iv, 16))
encryptor = AES.new(key.decode('hex'), AES.MODE_CTR, counter=ctr_e)

with open('output.pycrypto.mp4', 'wb') as fout:
    with open('input.mp4', 'rb') as fin:
        fout.write(encryptor.encrypt(fin.read()))

我认为它们应该相似,但事实并非如此:

I assume they are supposed to be similar, but it is not:

diff output.openssl.mp4 output.pycrypto.mp4
Binary files output.openssl.mp4 and output.pycrypto.mp4 differ

推荐答案

OpenSSL的行为符合预期(很遗憾,命令行缺少此事实的文档),并将给定的IV用作大字节序计数器的最左字节.换句话说,给定的字节是16字节计数器的最高有效部分.问题中的代码使用IV作为初始计数器值,即被解释为计数器的最低有效部分.

OpenSSL behaves as expected (fortunately, as documentation to this fact is missing for the command line) and uses the given IV as leftmost bytes of a big endian counter. In other words, the bytes given are the most significant part of the 16 byte counter. The code in the question uses the IV as initial counter value, i.e. it is interpreted as the least significant part of the counter.

现在我花了一些时间来修复Python代码,因为我必须解决的Counter类存在两个问题:

Now it took me some time to fix the Python code as there are two problems with the Counter class I had to work around:

  • 如果使用8字节的前缀,则计数器的大小应为64位而不是128位;这是一项设计功能,但是如果为计数器保留的位数很少(虽然当前设置为64位就可以),则可能会导致溢出
  • 默认初始计数器值设置为1,而CTR模式始终从0开始计数;这很可能是Counter设计中的一个错误

因此,事不宜迟:

from Crypto.Cipher import AES
from Crypto.Util import Counter

key = '7842f0a1ebc38f44e3e0c81943f68582'.decode('hex')
iv = 'd01f40dfc8ec8cd9'.decode('hex')

ctr_e = Counter.new(64, prefix=iv, initial_value=0)
encryptor = AES.new(key, AES.MODE_CTR, counter=ctr_e)

with open('output.pycrypto.mp4', 'wb') as fout:
    with open('input.mp4', 'rb') as fin:
        fout.write(encryptor.encrypt(fin.read()))

这篇关于使用openssl和PyCrypto进行AES_128_CTR加密的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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