gpt4 book ai didi

php - AES-128 OFB 使用 mcrypt (PHP) 和 pycryptodome (Python) 的不同之处

转载 作者:太空宇宙 更新时间:2023-11-04 09:30:19 25 4
gpt4 key购买 nike

免责声明:此处给出的所有示例都不安全,并且与良好实践相去甚远。此处使用的代码旨在用于 CTF 挑战并包含多个漏洞。

这是我真正关心的问题:使用相同的 key 、iv、模式和填充使用 mcrypt_encrypt 进行加密的结果与在 python 2.7 中使用 Crypto.cipher AES 进行相同的加密产生不同的密码,但仅当使用OFB模式。这是我的例子:

$key = 'SUPER_SECRET_KEY';
$iv = '0000000000000000';
$data = "this is a test";
$padding = 16 - (strlen($data) % 16);
$data .= str_repeat(chr($padding), $padding);
echo base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $data, MCRYPT_MODE_OFB, $iv));

结果是:k8Ss4ytOUNvcG96tr+rHdA==

现在是 python 示例:

from Crypto.Cipher import AES
from base64 import b64encode

key = 'SUPER_SECRET_KEY'
iv = '0'*16
data = "this is a test"
padding = 16 - (len(data) % 16)
data += chr(padding)*padding
print(b64encode(AES.new(key, AES.MODE_OFB, iv).encrypt(data)))

结果是:kzFpEHCJB+2k2498DhyAMw==

它只发生在 OFB 模式下。如果我将模式更改为 CBC(并且不更改任何其他内容),则两个结果将是相同的。知道发生了什么事吗?

编辑:在 PHP 中使用 openssl_encrypt 给我的结果与 python 代码相同。这让我相信 mcrypt_encrypt 中存在错误。

$key = "SUPER_SECRET_KEY";
$iv = "0000000000000000";
$data = "this is a test";
$padding = 16 - (strlen($data) % 16);
$data .= str_repeat(chr($padding), $padding);
$cipher = openssl_encrypt($data, "aes-128-ofb", $key, $options=OPENSSL_RAW_DATA, $iv);
echo base64_encode($cipher) ."\n";

最佳答案

我不确定您为什么要尝试使用 mcrypt 或 OFB 模式做任何事情 - 两者都是大多数密码学家试图忘记的过去的爆炸。还不清楚为什么要在流模式中使用填充,除非你正在解决 PyCrypto 错误(见下文)。


直接从PHP的文档中回答你的问题:

MCRYPT_MODE_OFB (output feedback, in 8-bit mode) is a stream cipher mode comparable to CFB, but can be used in applications where error propagation cannot be tolerated. It is recommended to use NOFB mode rather than OFB mode.

你可能应该使用:

MCRYPT_MODE_NOFB (output feedback, in n-bit mode) is comparable to OFB mode, but operates on the full block size of the algorithm.

其中“OFB”前的“N”是操作模式的 block 大小。


PyCrypto、PyCryptoDome 或 OpenSSL 均不存在此类文档。但是,它们似乎一次处理 128 位(根据 PyCrypto 错误报告),因为它出于某种原因错误地要求接收完整的明文 block 。


如果在 8 位或 128 位模式下使用,OFB 将产生不同的密文 - 除了第一个字节,它应该是相同的。 8 位模式与 mcrypt 或 OFB 本身一样是过去的爆炸;它使用完整的 block 加密每字节 (!) 以减少错误传播。

如果您需要流模式,请使用 CTR 模式,或者最好使用经过身份验证的密码,例如 GCM(在底层使用 CTR 模式)。这将比 8 位 OFB 更快(比 8 位 OFB)并且更安全。

关于php - AES-128 OFB 使用 mcrypt (PHP) 和 pycryptodome (Python) 的不同之处,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55997028/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com