【问题标题】:openssl -aes-128-ecb encryption doesn't match python Crypto.Cipher AES encryptionopenssl -aes-128-ecb 加密与 python Crypto.Cipher AES 加密不匹配
【发布时间】:2018-01-23 20:42:24
【问题描述】:

我正在尝试加密 16 字节的字符串“黎明攻击!!”使用密码为“黄色潜艇”的 AES-128。

在python中:

from Crypto.Cipher import AES
from base64 import b64encode

plaintext = 'Attack at dawn!!'
obj = AES.new("yellow submarine", AES.MODE_ECB)
ciphertext = obj.encrypt(plaintext)

print(b64encode(ciphertext).decode())

这给出了密文'kBKTLPWpU7Dpf/TiGo6p3w=='

现在在终端中使用 openssl。 plain.txt 是一个包含字符串 'Attack at Dawn!!' 的文本文件:

openssl enc -aes-128-ecb -nosalt -nopad -pass pass:"yellow submarine" -in plain.txt -out cipher.txt -a

这将返回 'X+fHjd97VRZLbH+BCgu6Xw==' 作为密文。

为什么它们不一样?

我尝试阅读文档或示例,但在 Internet 上没有找到任何有用的信息。我尝试更改 openssl 命令中的选项。我不知道如何解决这个问题。

【问题讨论】:

  • 为什么它们应该是一样的? openssl 使用专有的密钥派生算法将密码转换为密钥和 IV,而 pycrypto 执行其他操作。如果您使用-P 选项,您可以看到派生密钥和IV 是什么。在你的 pycrypto 代码中使用它们。
  • 天真地,我以为密码和密钥是一回事。我显然没有足够仔细地阅读手册,因为正如您所说,-P 会吐出实际的密钥(如果模式使用一个,则为 IV)。还有-K允许直接使用密钥。
  • @JamesKPolk 谢谢!这解决了我的困惑。

标签: python encryption openssl cryptography


【解决方案1】:

在 python 中,使用 Crypto.Cipher 中的 AES 进行加密需要一个密钥(16 个字节的字符串)和一个明文(16 个字节)并输出一个密文(16 个字节)。

要实现与 OpenSSL 相同的效果,您需要首先使用 -nosalt-nopad 禁用加盐和填充,以确保它接受 16 字节输入并返回 16 字节输出。提供密码会导致 OpenSSL 派生出自己的密钥。要覆盖它,请使用-K 选项(其中的密钥需要以十六进制形式给出)。或者,输入密码并指定 -p 将使 OpenSSL 吐出它使用的密钥。

  • 使用“黄色潜艇”键:

蟒蛇

from Crypto.Cipher import AES
from base64 import b64encode

plaintext = 'Attack at dawn!!'
obj = AES.new("yellow submarine", AES.MODE_ECB)
ciphertext = obj.encrypt(plaintext)

print(b64encode(ciphertext).decode())

openssl

enc -aes-128-ecb openssl enc -aes-128-ecb -nosalt -nopad -K 79656c6c6f77207375626d6172696e65 -in plain.txt -out cipher.txt -a

这为这两种方法提供了 'kBKTLPWpU7Dpf/TiGo6p3w=='。

  • 使用 OpenSSL 密码“黄色潜水艇”:

    openssl enc -aes-128-ecb -nosalt -nopad -p -pass pass:"黄色潜艇" -in plain.txt -out cipher.txt -a

这会将密钥输出为“A35EC217E15C1DD258201A184814897C”。要将其与 Crypto.Cipher 一起使用,我们首先需要将其转换为十六进制。

from Crypto.Cipher import AES
from base64 import b64encode

hex_key = 'A35EC217E15C1DD258201A184814897C'
key = bytes.fromhex(hex_key)

plaintext = 'Attack at dawn!!'
obj = AES.new(key, AES.MODE_ECB)
ciphertext = obj.encrypt(plaintext)

print(b64encode(ciphertext).decode())

这两种方法都给出了“X+fHjd97VRZLbH+BCgu6Xw==”。

  • 要回答最后一个问题:您应该更仔细地阅读 OpenSSL enc 手册,并发现 -p-P-k 选项。

【讨论】:

    猜你喜欢
    • 2015-06-15
    • 2019-04-18
    • 2016-05-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-09
    • 1970-01-01
    • 2015-11-01
    相关资源
    最近更新 更多