如何生成好盐 - 我的函数是否足够安全?

2022-08-30 12:12:59

这是我用来生成随机盐的函数:

function generateRandomString($nbLetters){
    $randString="";
    $charUniverse="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
    for($i=0; $i<$nbLetters; $i++){
       $randInt=rand(0,61);
        $randChar=$charUniverse[$randInt];
        $randString=$randomString.$randChar;
    }
    return $randomString;
}

这是针对非商业网站的。它仅用于生成盐(存储在数据库中,并与用户提交的pw一起用于散列)。

这合适吗?我应该使用更大的字符子集,如果是这样,在PHP中是否有一种简单的方法可以做到这一点?


答案 1

如果要散列密码,则应使用不需要生成自己的盐的现代散列算法。使用弱哈希算法会给您和您的用户带来危险。我最初的答案是八年前写的。时代变了,密码哈希现在容易多了。

您应该始终使用内置函数来散列/检查密码。在任何时候使用自己的算法都会带来大量不必要的风险。

对于 PHP,请考虑将 password_hash() 与算法结合使用。没有必要提供自己的盐。PASSWORD_BCRYPT

以下是我最初的答案,供后人参考:


警告:根据 uniqid 的文档,以下实现不会生成不可预测的盐。

php sha1 页面

$salt = uniqid(mt_rand(), true);

这看起来比你提出的更简单,更有效(因为每个都是独一无二的)。


答案 2

如果你在Linux上,可能是你随机性的最佳来源。它由操作系统本身提供,因此它保证比任何PHP内置函数都可靠得多。/dev/urandom

$fp = fopen('/dev/urandom', 'r');
$randomString = fread($fp, 32);
fclose($fp);

这将为你提供 32 字节的随机 blob。您可能希望通过诸如使其清晰易读之类的方式来传递它。无需自己玩弄角色。base64_encode()

编辑2014年:在 PHP 5.3 及更高版本中,是获取一堆随机字节的最简单方法。在*nix系统上,它使用幕后。在Windows系统上,它使用内置于OpenSSL库中的不同算法。openssl_random_pseudo_bytes()/dev/urandom

相关: https://security.stackexchange.com/questions/26206

相关:我应该使用urandom还是openssl_random_pseudo_bytes?


推荐