5

mcrypt_get_iv_size 的 PHP 文档中指出,当算法/块模式组合不使用 IV 时,返回值将为零:

返回初始化向量 (IV) 的大小(以字节为单位)。出错时,函数返回 FALSE。如果在指定的密码/模式组合中忽略 IV,则返回零。

当我使用 MCRYPT_DES 作为算法并使用 MCRYPT_MODE_ECB 作为模式调用此函数时,它返回 8(八)而不是预期的 0(零)。

我的理解是欧洲央行没有也不能使用 IV,因此我期望零值。这是不正确的,是文档不正确,还是我遗漏了其他东西?

以下代码段演示了该问题:

<?php
// I expect this call to return zero.
$size = mcrypt_get_iv_size(MCRYPT_DES, MCRYPT_MODE_ECB);
echo 'IV Size: ' . $size . PHP_EOL;

请注意,我实际上并没有将 ECB 用于现实世界的加密,我只是想找到一种可靠的方法来确定任意算法/模式是否需要 IV。(我注意到 mcrypt 库有一个函数“mcrypt_enc_mode_has_iv”,但似乎没有等效的 PHP 函数)。

我将 PHP v5.3.12 与 libmcrypt 2.5.8_1 一起使用。

更新可能的解决方法:

查看 libmcrypt 源,似乎 mcrypt_enc_get_iv_size() 将始终返回任何块密码模式的块大小,但回退到“询问”流模式的算法。

int mcrypt_enc_get_iv_size(MCRYPT td)
{
    if (mcrypt_enc_is_block_algorithm_mode(td) == 1) {
        return mcrypt_enc_get_block_size(td);
    } else {
        return mcrypt_get_algo_iv_size(td);
    }
}

mcrypt_get_algo_iv_size() 调用被转发到算法库的 _mcrypt_get_algo_iv_size() 函数。所以希望这意味着如果我手动处理 ECB 案例,它应该为那些需要流模式下的 IV 的算法产生正确的结果。

4

1 回答 1

1

你是对的,ECB 不使用 IV,因为它也在PHP 文档中mcrypt_get_iv_size指出:

常量之一MCRYPT_MODE_modename,或以下字符串之一:“ecb”、“cbc”、“cfb”、“ofb”、“nofb”或“stream”。在 ECB 模式下,IV 被忽略,因为该模式不需要它。您需要在加密和解密阶段都拥有相同的 IV(想想:起点),否则您的加密将失败。

为什么mcrypt_get_iv_size(MCRYPT_DES, MCRYPT_MODE_ECB)返回 8 是奇数。有意或无意,你应该忽略它。

于 2012-07-25T01:57:35.640 回答