在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 的算法产生正确的结果。