审核我的PHP函数以生成加密安全密码

时间:2013-06-20 04:32:28

标签: php security random passwords cryptography

我在PHP中编写了一个功能,为我的应用生成随机密码(仅限0-9a-zA-Z)。生成的密码必须是加密安全的,并且尽可能随机。 I.E.密码很敏感。

我所做的一个重要工作就是每次都会混淆$possible个字符,所以即使mt_rand()不是真正随机的,也不应该是可预测的。

我的功能中有任何建议的更改或安全问题吗?使用openssl_random_pseudo_bytes()代替mt_rand()真的会使算法更强大,更安全吗?

    public function generate_random($length = 15) {
        $random = "";
        $possible = "1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
        $possible = str_shuffle($possible);

        $maxlength = strlen($possible);

        if ($length > $maxlength) {
            $length = $maxlength;
        }

        $i = 0;

        while ($i < $length) {
            $random .= substr($possible, mt_rand(0, $maxlength-1), 1);
            $i++;
        }

        return $random;
    }

感谢。

4 个答案:

答案 0 :(得分:2)

要生成非常随机的内容,您必须使用操作系统的随机源。从这个源读取后,您需要将字节编码为您选择的字母。

一个简单的转换是base64编码,但这将包括'+'和'/'字符。要仅从字母和数字中获取字符,您需要base62编码,或者只需将这些字符替换为其他字符。

/**
 * Generates a random string of a given length, using the random source of
 * the operating system. The string contains only characters of this
 * alphabet: +/0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
 * @param int $length Number of characters the string should have.
 * @return string A random base64 encoded string.
 */
function generateRandomBase64String($length)
{
  if (!defined('MCRYPT_DEV_URANDOM')) die('The MCRYPT_DEV_URANDOM source is required (PHP 5.3).');

  // Generate random bytes, using the operating system's random source.
  // Since PHP 5.3 this also uses the random source on a Windows server.
  // Unlike /dev/random, the /dev/urandom does not block the server, if
  // there is not enough entropy available.
  $binaryLength = (int)($length * 3 / 4 + 1);
  $randomBinaryString = mcrypt_create_iv($binaryLength, MCRYPT_DEV_URANDOM);
  $randomBase64String = base64_encode($randomBinaryString);
  return substr($randomBase64String, 0, $length);
}

代码是此class的一部分,请查看函数generateRandomBase62String()以获取完整示例。

答案 1 :(得分:1)

将伪随机性添加到伪随机字符串将不会增加熵。唯一的方法是使用更好的随机数生成器。

可能重复:Secure random number generation in PHP

答案 2 :(得分:1)

如果通过加密安全,你的意思是你打算在某个地方使用密码作为密钥,重要的是要意识到你的空间不够大。每个有62个可能性的15个字符小于90位,这与RSA-1024一样强,并且今天被认为是不安全的。

但是,你应该首先不做这样的事情。如果您确实需要一个人类可读的字符串,该字符串映射到可用作加密密钥的内容,请使用类似PBKDF2的内容。

最后,改变字符串并不会增加有效的随机性。只要您不直接使用它作为键,您的功能就可以了 - 记得首先根据常用密码字典检查输出 (如密码破解者的密码列表)并拒绝这些。

答案 3 :(得分:0)

这不是您的问题的答案,但使用此函数生成仅包含(0-9a-z,A-Z)的随机随机密码似乎是可行的

$password = base64_encode(openssl_random_pseudo_bytes(20, $strong));
$newstr = preg_replace('/[^a-zA-Z0-9\']/', '', $password);
echo $newstr;