我强烈建议在 unix 系统上将 /dev/urandom 或 Windows 平台上的 crypto-api 作为密码的熵源。
我再怎么强调也不过分,意识到哈希值不是神奇的熵增加设备的重要性。以这种方式滥用它们并不比在散列之前使用种子和rand()数据更安全,我相信你认识到这不是一个好主意。种子会抵消(确定性mt_rand()),因此即使包含它也没有意义。
人们认为他们是聪明和聪明的,他们的劳动结果是脆弱的系统和设备,使他们的系统的安全性和其他系统的安全性(通过糟糕的建议)处于不必要的危险之中。
两个错误不能成为一个正确。一个系统的强大程度取决于其最薄弱的部分。这不是接受使它更加不安全的许可或借口。
以下是一些PHP代码,用于获取安全的随机128位字符串,来自Mark Seecof在 php.net 的注释:
“如果你需要一些伪随机位用于安全或加密目的(例如,随机IV用于块密码,随机盐用于密码哈希),mt_rand()是一个糟糕的来源。在大多数Unix / Linux和/或MS-Windows平台上,您可以从操作系统或系统库获得更高级别的伪随机位,如下所示:
<?php
// get 128 pseudorandom bits in a string of 16 bytes
$pr_bits = '';
// Unix/Linux platform?
$fp = @fopen('/dev/urandom','rb');
if ($fp !== FALSE) {
$pr_bits .= @fread($fp,16);
@fclose($fp);
}
// MS-Windows platform?
if (@class_exists('COM')) {
// http://msdn.microsoft.com/en-us/library/aa388176(VS.85).aspx
try {
$CAPI_Util = new COM('CAPICOM.Utilities.1');
$pr_bits .= $CAPI_Util->GetRandom(16,0);
// if we ask for binary data PHP munges it, so we
// request base64 return value. We squeeze out the
// redundancy and useless ==CRLF by hashing...
if ($pr_bits) { $pr_bits = md5($pr_bits,TRUE); }
} catch (Exception $ex) {
// echo 'Exception: ' . $ex->getMessage();
}
}
if (strlen($pr_bits) < 16) {
// do something to warn system owner that
// pseudorandom generator is missing
}
?>
注意:在你的代码中,保留读取 /dev/urandom 的尝试和访问 CAPICOM 的尝试通常是安全的,尽管每个尝试都会在另一个平台上以静默方式失败。把它们都留在那里,这样你的代码就会更有便携性。