使用PHP创建加密安全令牌的标准方法似乎是:
$token = bin2hex(openssl_random_pseudo_bytes(16));
我理解你是否正在使用Linux(我总是这样做),因为它使用/ dev / urandom - 根据操作系统中发生的所有事情而改变 - 这使得它几乎无法预测
我的功能更像是这样,所以我可以通过字符长度而不是长度来实现(虽然我不会真正使用它,见下文):
function token($charLength = 32) {
// Each byte produces 2 hexadecimal characters so bit length should be half the char length
$bitLength = $charLength / 2;
// Generate token
$token = bin2hex(openssl_random_pseudo_bytes($bitLength));
return $token;
}
这种不可预测性是否安全?我无法帮助他们认为较少安全,因为输出是十六进制的,因此比具有相同数量的字符串的字符串更难以猜测或暴力。其余的字母,大写字母,其他符号等。
这是为什么当人们提到令牌时他们指的是比特长度而不是字符长度?
改为考虑:
function randomString($length,
$alpha = true,
$alphau = true,
$numeric = true,
$specialChars = '') {
$string = $specialChars;
if($alpha === true) {
$string .= 'abcdefghijklmnopqrstuvwxyz';
}
if($alphau === true) {
$string .= 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
}
if($numeric === true) {
$string .= '0123456789';
}
$array = str_split($string);
$string = '';
for($counter = 0; $counter < $length; $counter ++) {
$string .= $array[array_rand($array)];
}
return $string;
}
在Web开发的上下文中,您何时将第一个函数用于第二个函数:
在所有情况下,我都会使用randomString()而不是token(),所以我想我是否以及在上述任何一种情况下我是否错了。
关于以上几点的理由:
答案 0 :(得分:1)
随机数生成器的主要关注点通常不是创建的输出,而是生成此数据的可预测性。您的基本问题是为什么不在openssl_random_pseudo_bytes上使用array_rand(内部使用php_rand)进行加密。答案与每个函数采用的技术有关,array_rand是一种更可预测(并且可重现)的方法。请参阅PádraicBrady的文章“在PHP中预测随机数 - 它比您想象的更容易!”更多详情:http://blog.astrumfutura.com/2013/03/predicting-random-numbers-in-php-its-easier-than-you-think/。
关于随机数发生器的输出,与蛮力攻击相关的密码/密钥强度通常以熵测量。这通常以比特列出,越多越好。关于密码强度的维基百科页面(http://en.wikipedia.org/wiki/Password_strength)有一些很好的参考表,用于确定不同长度的密码的熵级别,并使用各种字符类型组合。 openssl_random_pseudo_bytes()函数利用所有二进制/十六进制值,每个符号产生一个完整的8位熵。你的randomString()函数最多会产生每个符号5.954位的熵。
在所有与安全相关的情况下,应使用加密强随机数,其中猜测其中一个数字的能力会以某种方式对您的网站产生负面影响。 4列表中唯一一个我看到不需要加密强随机数的项目是哈希的盐值。盐值必须是普遍唯一的。它当然可以由加密随机数生成器(CRNG)生成,但这不是必需的,因为结果值可以公开。见https://security.stackexchange.com/questions/8246/what-is-a-good-enough-salt-for-a-saltedhash