这种密码散列和匹配方法的安全性如何?
How secure is this method of password hashing and matching?
我从一系列帖子和一些先验知识中获取信息来实现以下哈希算法。然而,有很多关于哪些实现是安全的和不安全的讨论。我的方法如何衡量?安全吗?
public static function sha512($token,$cost = 50000,$salt = null) {
$salt = ($salt == null) ? (generateToken(32)) : ($salt);
$salt = '$rounds=' . $cost . '$' . $salt . ' $';
return crypt($token, $salt);
}
public static function sha512Equals($token,$hash) {
return (crypt($token,$hash) == $hash);
}
public static function generateToken($length,$characterPool = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ') {
$token = '';
$max = mb_strlen($characterPool);
for ($i = 0;$i < $length;$i++){
$token .= $characterPool[cryptorand(0,$max)];
}
return $token;
}
public static function cryptorand($min, $max) {
$range = $max - $min;
if ($range < 0)
return $min;
$log = log($range, 2);
$bytes = (int) ($log / 8) + 1; // length in bytes
$bits = (int) $log + 1; // length in bits
$filter = (int) (1 << $bits) - 1; // set all lower bits to 1
do {
$rnd = hexdec(bin2hex(openssl_random_pseudo_bytes($bytes)));
$rnd = $rnd & $filter; // discard irrelevant bits
} while ($rnd >= $range);
return $min + $rnd;
}
那么这个方法安全吗? PHP 中是否有更安全的方法用于散列令牌并稍后与令牌匹配?非常感谢任何批评。
不,因为您最终信任 crypt
而您没有使用 sha512Equals
中的时间常数比较。
也可能存在特定于平台的问题:openssl_random_pseudo_bytes
不必是加密安全的。我不确定你是怎么知道 crypt
使用 SHA-512 的。
您在 cryptorand
中的计算略有偏差(例如,$log
的值恰好位于字节边界上),但幸运的是,do/while 循环对其进行了检查。
请改用 password_hash
或 password_verify
功能。
我从一系列帖子和一些先验知识中获取信息来实现以下哈希算法。然而,有很多关于哪些实现是安全的和不安全的讨论。我的方法如何衡量?安全吗?
public static function sha512($token,$cost = 50000,$salt = null) {
$salt = ($salt == null) ? (generateToken(32)) : ($salt);
$salt = '$rounds=' . $cost . '$' . $salt . ' $';
return crypt($token, $salt);
}
public static function sha512Equals($token,$hash) {
return (crypt($token,$hash) == $hash);
}
public static function generateToken($length,$characterPool = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ') {
$token = '';
$max = mb_strlen($characterPool);
for ($i = 0;$i < $length;$i++){
$token .= $characterPool[cryptorand(0,$max)];
}
return $token;
}
public static function cryptorand($min, $max) {
$range = $max - $min;
if ($range < 0)
return $min;
$log = log($range, 2);
$bytes = (int) ($log / 8) + 1; // length in bytes
$bits = (int) $log + 1; // length in bits
$filter = (int) (1 << $bits) - 1; // set all lower bits to 1
do {
$rnd = hexdec(bin2hex(openssl_random_pseudo_bytes($bytes)));
$rnd = $rnd & $filter; // discard irrelevant bits
} while ($rnd >= $range);
return $min + $rnd;
}
那么这个方法安全吗? PHP 中是否有更安全的方法用于散列令牌并稍后与令牌匹配?非常感谢任何批评。
不,因为您最终信任 crypt
而您没有使用 sha512Equals
中的时间常数比较。
也可能存在特定于平台的问题:openssl_random_pseudo_bytes
不必是加密安全的。我不确定你是怎么知道 crypt
使用 SHA-512 的。
您在 cryptorand
中的计算略有偏差(例如,$log
的值恰好位于字节边界上),但幸运的是,do/while 循环对其进行了检查。
请改用 password_hash
或 password_verify
功能。