gpt4 book ai didi

php - 什么会导致 crypt 产生错误的验证?

转载 作者:可可西里 更新时间:2023-10-31 23:14:47 25 4
gpt4 key购买 nike

我在构建门户网站时遇到问题,因此决定通过小型压力测试进一步调查。该测试为一个指定密码生成了 4,000/10,000/50,000 种不同的盐。代码如下:

$Incline = 0;
$Max = 4000;
$Auth = new Authentication();
$FalseCounter = 0;
$TrueCounter = 0;
while ($Incline < $Max){
$PasswordString = "1";
$Encrypted_Pass = $Auth->Hash_Password($PasswordString);
$Check = crypt($PasswordString,$Encrypted_Pass['Salt']);

if ($Check === $Encrypted_Pass['Password']){
$TrueCounter++;
}else{
$FalseCounter++;
}
if ($Incline === $Max){
break;
}
$Incline++;
}

echo 'Of '.$Max.' Checks '.$FalseCounter.' False Returns & '.$TrueCounter.' True Returns';

$Auth->Hash_Password 为:

public $Salt = null;
public function SetSalt(){
$ByteSize = mcrypt_get_iv_size(MCRYPT_CAST_256, MCRYPT_MODE_CFB);
$Salt = mcrypt_create_iv($ByteSize, MCRYPT_DEV_RANDOM);
$this->Salt = $Salt;
if (!is_null($this->Salt)){
return true;
}
return false;
}
public function Hash_Password($Password){
$this->SetSalt();
$Return_Array = array();
$Return_Array['Salt'] = $this->Salt;
$Return_Array['Password'] = crypt($Password,$this->Salt);
return $Return_Array;
}

现在,在显示代码之后。我的输出如下(多次刷新)

  1. Of 4000 Checks 22 False Returns & 3978 True Returns

  2. Of 4000 Checks 15 False Returns & 3985 True Returns

  3. Of 4000 Checks 15 False Returns & 3985 True Returns

  4. Of 4000 Checks 10 False Returns & 3990 True Returns

  5. Of 4000 Checks 6 False Returns & 3994 True Returns

  6. Of 10000 Checks 40 False Returns & 9960 True Returns

  7. Of 10000 Checks 43 False Returns & 9957 True Returns

  8. Of 50000 Checks 196 False Returns & 49804 True Returns

尽管失败率很小。问题仍然存在。关于密码加密,这不应该是所有密码比较的100%吗?

因此,总体问题是:什么会导致这种影响?这可能是我的编码吗?还是完全完美的 PHP 中的缺陷?

最佳答案

似乎 crypt 受到“空字节中毒”的影响。所有测试都将通过,如果您将 SetSalt 方法更改为:

<?php
public function SetSalt()
{
$ByteSize = mcrypt_get_iv_size(MCRYPT_CAST_256, MCRYPT_MODE_CFB);
do {
$Salt = mcrypt_create_iv($ByteSize, MCRYPT_DEV_RANDOM);

// Remove null byte from salt
$this->Salt = str_replace(chr(0), '', $Salt);

} while ($this->Salt !== $Salt); // Retry until salt without null byte is generated

if (!is_null($this->Salt)) {
return true;
}
return false;
}

之后所有的测试都通过了:

$ php crypt_test.php
Of 4000 Checks 0 False Returns & 4000 True Returns

如果您想阅读更多关于空字节的信息,您可以从这里开始:http://www.madirish.net/401

为了更好地说明,这里是失败测试的示例输出:

string(34) "$1$iyJhOmt2$23uOXEcjWr2GcjSMqKpHk0"
array(2) {
'Salt' =>
string(16) "\000g-Ŕ=(
��A��n0"
'Password' =>
string(34) "$1$QCbFiEDR$g3RDS7LK3m88K7XPqjF5O."
}

您可以在此处看到空字节:\0

对于所有懒惰的人,这里是我使用的完整(固定)测试脚本;)

<?php

class Authentication
{
public $Salt = null;

public function SetSalt()
{
$ByteSize = mcrypt_get_iv_size(MCRYPT_CAST_256, MCRYPT_MODE_CFB);
do {
$Salt = mcrypt_create_iv($ByteSize, MCRYPT_DEV_RANDOM);

// Remove null byte from salt
$this->Salt = str_replace(chr(0), '', $Salt);
} while ($this->Salt !== $Salt);

if (!is_null($this->Salt)) {
return true;
}
return false;
}

public function Hash_Password($Password)
{
$this->SetSalt();
$Return_Array = array();
$Return_Array['Salt'] = $this->Salt;
$Return_Array['Password'] = crypt($Password, $this->Salt);
return $Return_Array;
}
}


$Incline = 0;
$Max = 4000;
$Auth = new Authentication();
$FalseCounter = 0;
$TrueCounter = 0;
while ($Incline < $Max) {
$PasswordString = "1";
$Encrypted_Pass = $Auth->Hash_Password($PasswordString);
$Check = crypt($PasswordString, $Encrypted_Pass['Salt']);

if ($Check === $Encrypted_Pass['Password']) {
$TrueCounter++;
} else {
var_dump($Encrypted_Pass, $Check);
$FalseCounter++;
}
if ($Incline === $Max) {
break;
}
$Incline++;
}

echo 'Of ' . $Max . ' Checks ' . $FalseCounter . ' False Returns & ' . $TrueCounter . ' True Returns' . "\n";

快乐编码

关于php - 什么会导致 crypt 产生错误的验证?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32161460/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com