加密安全的随机字符串函数 [英] Cryptographically Secure Random String Function

查看:98
本文介绍了加密安全的随机字符串函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

目标:查找在密码上最安全的随机字符串生成器。在字符串中使用字母,数字和可能的特殊字符。

我一直在这里和其他地方读书,但我仍然听到很多不同的答案/意见。

I have been reading on here and other places, but I still hear so many different answers/opinions. Can people who are up to date and knowledgeable about security and cryptography chime in here.

以下功能将用于生成8个字符的随机密码,并生成128个字符。字符随机令牌。

The following functions will be used to generate a 8 character random password and also generate a 128 character random token.

功能1:

/**
 * Used for generating a random string.
 *
 * @param int $_Length  The lengtyh of the random string.
 * @return string The random string.
 */
function gfRandomString($_Length) {
    $alphabet = "abcdefghijklmnopqrstuwxyzABCDEFGHIJKLMNOPQRSTUWXYZ0123456789";
    $pass = array(); //remember to declare $pass as an array
    $alphaLength = strlen($alphabet) - 1; //put the length -1 in cache
    for ($i = 0; $i < $_Length; $i++) {
        $n = rand(0, $alphaLength);
        $pass[] = $alphabet[$n];
    }
    return implode($pass); //turn the array into a string
}

函数2:

PHP.net文档说:
crypto_strong
如果传递给函数,这将包含一个布尔值,该布尔值确定所使用的算法是否在密码学上很强,例如可以安全地用于GPG,密码等。如果正确,则为TRUE,否则为FALSE。

The PHP.net docs say: crypto_strong: If passed into the function, this will hold a boolean value that determines if the algorithm used was "cryptographically strong", e.g., safe for usage with GPG, passwords, etc. TRUE if it did, otherwise FALSE.

那是基于服务器的吗?如果我对其进行了一次测试,并且它能够生成一个crypto_strong字符串,它将始终能够生成吗?还是我需要每次检查并创建一个循环,直到它生成crypto_strong字符串。

So is that based on the the server? If I test it once, and it is able to generate a crypto_strong string, will it always be able to? Or would I need to check each time and create a loop until it generates a crypto_strong string.

/**
 * Used for generating a random string.
 *
 * @param int $_Length  The length of bits.
 * @return string The random string.
 */
function gfSecureString($_Length) {
    $Str = bin2hex(openssl_random_pseudo_bytes($_Length));
    return $Str; 
}

我欢迎任何提高密码强度的建议。

I welcome any suggestions to improve the cryptographic strength.

推荐答案

所以您想在PHP中安全地生成随机字符串。问题中的两个函数都不能满足您的需求,但是 rand()解决方案是这两个函数中最差的一个。 rand()是不安全的,而 bin2hex(openssl_random_pseudo_bytes())会限制您的输出字符集。

So you want to securely generate random strings in PHP. Neither of the two functions in the question will give you what you want, but the rand() solution is the worst of the two. rand() is not secure, while bin2hex(openssl_random_pseudo_bytes()) limits your output character set.

此外, openssl_random_pseudo_bytes()在极端条件或特殊设置下可能不可靠

Also, openssl_random_pseudo_bytes() might not be reliable under extreme conditions or exotic setups.

据我了解, crypto_strong 仅在 RAND_pseudo_bytes()时设置为 false 无法返回任何数据。如果OpenSSL在调用时未植入种子,它将以静默方式返回弱(且可能可预测)的伪随机字节。通过PHP,您无法确定它是否也是随机的。

From what I understand, crypto_strong will only be set to false if RAND_pseudo_bytes() fails to return any data. If OpenSSL is not seeded when it's invoked, it will silently return weak (and possibly predictable) pseudorandom bytes. You have no way, from PHP, to determine if it's random either.

如果您希望获得针对PHP 5.x进行了实质性审查的解决方案,请使用 RandomLib 。 / p>

If you want a solution that has received substantial review for PHP 5.x, use RandomLib.

$factory = new RandomLib\Factory;
$generator = $factory->getMediumStrengthGenerator();
$randomPassword = $generator->generateString(20, $alphabet);



替代解决方案



如果您愿意而不是使用RandomLib(即使纯粹是因为您想要使用其他选项),也可以使用 random_int() 当PHP 7发布时。如果您不能等到那时,请查看我们的 random_compat 项目。

如果您恰好正在使用加密库,请 libsodium ,您可以像这样生成随机数:

If you happen to be using the cryptography library, libsodium, you can generate random numbers like so:

/**
 * Depends on the PECL extension libsodium
 * 
 * @link https://stackoverflow.com/a/31498051/2224584
 * 
 * @param int $length How long should the string be?
 * @param string $alphabet Contains all of the allowed characters
 * 
 * @return string
 */
function sodium_random_str($length, $alphabet = 'abcdefghijklmnopqrstuvwxyz')
{
    $buf = '';
    $alphabetSize = strlen($alphabet);
    for ($i = 0; $i < $length; ++$i) {
        $buf .= $alphabet[\Sodium\randombytes_uniform($alphabetSize)];
    }
    return $buf;
}

请参见此答案,例如使用 random_int()的代码。如果有需要,我不想重复将来进行代码更新的工作。

See this answer for example code that uses random_int(). I'd rather not duplicate the effort of updating the code in the future, should the need ever arise.

这篇关于加密安全的随机字符串函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆