2

我目前正在开展一个需要闭环电子邮件验证的项目。作为该过程的一部分,我需要生成一个随机哈希字符串,该字符串可以附加到发送给用户的链接中。当他们单击链接时,他们将被定向到我的网站,此时应用程序将确认哈希并完成注册过程。对于我一直在使用的所有哈希:

hash('sha256', $string);

但是对于这个过程,我需要$string用一个随机值来播种。我有 Zend Framework 可用,并希望做这样的事情:

$crypt = new Zend_Filter_Encrypt_Mcrypt(array());

$hash = hash('sha256', $crypt->getVector());

我的问题是,这是生成随机哈希码的可行算法吗?

这是Zend_Filter_Encrypt_Mcrypt::setVector()方法(生成通过返回的值getVector()

public function setVector($vector = null)
{
    $cipher = $this->_openCipher();
    $size   = mcrypt_enc_get_iv_size($cipher);
    if (empty($vector)) {
        $this->_srand();
        if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN' && version_compare(PHP_VERSION, '5.3.0', '<')) {
            $method = MCRYPT_RAND;
        } else {
            if (file_exists('/dev/urandom') || (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN')) {
                $method = MCRYPT_DEV_URANDOM;
            } elseif (file_exists('/dev/random')) {
                $method = MCRYPT_DEV_RANDOM;
            } else {
                $method = MCRYPT_RAND;
            }
        }
        $vector = mcrypt_create_iv($size, $method);
    } else if (strlen($vector) != $size) {
        require_once 'Zend/Filter/Exception.php';
        throw new Zend_Filter_Exception('The given vector has a wrong size for the set algorithm');
    }

    $this->_encryption['vector'] = $vector;
    $this->_closeCipher($cipher);

    return $this;
}
4

2 回答 2

3

我对 ZF 不是很熟悉,但是其中包含这个词Encrypt的东西听起来像是错误的方法。

->getVector()听起来类似于初始化向量在对称加密中的作用;问题是这样的向量不需要是密码安全的,只是随机的。例如,它很可能只是实现为uniqid(mt_rand())或什么。

->getVector()用于mcrypt首先初始化加密密码以了解 IV 应该有多大;这通常是 8 个字节,但在很大程度上取决于所用密码的块大小。问题是,你没有加密任何东西;你只想要一个随机序列。

获得随机序列的更好方法是使用openssl_random_pseudo_bytes()8 个字节的大小。

在没有它的情况下,您还可以从熵文件中读取,例如/dev/random/dev/urandom。之后,您可以运行它binh2hex()以生成十六进制字符串。

像这样的东西非常初级,但应该适用于 Linux'y 系统:

$rnd = bin2hex(file_get_contents('/dev/urandom', false, null, 0, 8));

作为 Windows 的后备方案,您仍然可以使用以下内容:

$rnd = hash('sha256', uniqid(mt_rand(), true));
于 2012-12-06T23:24:08.477 回答
0

您可能想查看具有相当全面的随机生成功能套件的ircmaxell 的CryptLib 。如果您使用中等强度的随机字符串生成器,如下所示:

$generator = ( new CryptLib\Random\Factory() )->getMediumStrengthGenerator();
$string = $generator->generateString(LENGTH);

该库将使用多个加密安全源并通过混合器运行它们以生成字符串。如果您只想要一个简单的解决方案并且不想使用 openssl 重新编译 PHP,那么值得一试。

请参阅有关安全字符串生成的自述文件。

于 2012-12-06T23:42:36.620 回答