与此 python 片段等效的 openssl AES-CFB-128 命令行是什么?

What is the openssl AES-CFB-128 command line equivalent to this python snippet?

我有这个 python 片段,它一直对我有用:

from Crypto.Cipher import AES # pip install pycryptodome
import os

def aes_cfb(data, key, iv):
    ctx = AES.new(key, AES.MODE_CFB, iv = iv, segment_size = 128)
    decrypted = ctx.decrypt(data)
    return decrypted

filesize = os.stat('./config_enc.bin').st_size

with open('./config_enc.bin','rb') as rf:
    data = rf.read(filesize)
    decrypted = aes_cfb(data, b'3398699acebda0da', b'b39a46f5cc4f0d45')

with open('./config.xml', 'wb') as wf:
    wf.write(decrypted)

所以我决定使用openssl.exe作为命令行工具进行测试(因为它比python代码更实用),但它对我没有用。

这是我使用版本 OpenSSL 1.1.1j 16 Feb 2021 使用的命令行工具:

openssl.exe enc -d -aes-128-cfb -in config_enc.bin -out config.xml -K 3398699acebda0da -iv b39a46f5cc4f0d45

那么,我在这里做错了什么?或者 OpenSSL 可能根本不兼容!如果是这样,那我应该放弃它并用其他东西代替它。

加密文件:https://filebin.net/xm85gfwfauf4mutv(从现在起 1 周后过期)。

首先,对于 OpenSSL 命令行,密钥(-K 选项)和 IV(-iv 选项)必须提供十六进制值。如果我们提供您的值,它们很短,它们会用 0s 填充并带有警告;

hex string is too short, padding with zero bytes to length

您提供了 16 个十六进制,但 AES-128 需要 32 个。让我们 运行 使用扩展密钥和 IV;

openssl enc -e -aes-128-cfb \
     -in plain.txt \
     -out encrypted.txt \
     -K 3398699acebda0dab39a46f5cc4f0d45 \
     -iv b39a46f5cc4f0d45b39a46f5cc4f0d45`

with plaintext 12345678 then output �4PcGp� as encrypted value.

现在有了 str(bytearray.fromhex('HEXVALUE')),我们可以将十六进制字符串转换为字节,并在您的代码中将它们用作;

from Crypto.Cipher import AES # pip install pycryptodome
import os

def aes_cfb(data, key, iv):
    ctx = AES.new(key, AES.MODE_CFB, iv = iv, segment_size = 128)
    decrypted = ctx.decrypt(data)
    return decrypted

filesize = os.stat('./encrypted.txt').st_size

with open('./encrypted.txt','rb') as rf:
    data = rf.read(filesize)
    decrypted = aes_cfb(data, 
                        str(bytearray.fromhex('3398699acebda0dab39a46f5cc4f0d45'),
                        str(bytearray.fromhex('b39a46f5cc4f0d45b39a46f5cc4f0d45') 
                       )

with open('./config.xml', 'wb') as wf:
    wf.write(decrypted)

现在它们与安全密钥大小兼容。


您声称此密钥是字节 3398699acebda0da,但它是十六进制的,即仅包含十六进制字符。如果您正在使用它,这意味着您的有效密钥空间是 64 位。按照今天的标准,这是不安全的。

假设这仅用于测试,那么您可以通过一些命令将其转换为十六进制,如 Linux's hexdump command.

或者在 Python 中使用 b'3398699acebda0da'.hex() 将字节转换为十六进制并作为十六进制提供给 OpenSSL。