gpt4 book ai didi

php - 关于恒定时间算法和字符串比较的解释

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:33:57 25 4
gpt4 key购买 nike

我无法理解两种不同的字符串比较方式。给出以下比较两个字符串的函数。该函数在 Symfony-Framework 安全组件中用于在用户登录过程中比较密码。

/**
* Compares two strings.
*
* This method implements a constant-time algorithm to compare strings.
*
* @param string $knownString The string of known length to compare against
* @param string $userInput The string that the user can control
*
* @return Boolean true if the two strings are the same, false otherwise
*/
function equals($knownString, $userInput)
{
// Prevent issues if string length is 0
$knownString .= chr(0);
$userInput .= chr(0);

$knownLen = strlen($knownString);
$userLen = strlen($userInput);

$result = $knownLen - $userLen;

// Note that we ALWAYS iterate over the user-supplied length
// This is to prevent leaking length information
for ($i = 0; $i < $userLen; $i++) {
// Using % here is a trick to prevent notices
// It's safe, since if the lengths are different
// $result is already non-0
$result |= (ord($knownString[$i % $knownLen]) ^ ord($userInput[$i]));
}

// They are only identical strings if $result is exactly 0...
return 0 === $result;
}

来源:origin snippet

我无法理解 equals() 函数与简单比较 === 之间的区别。我写了一个简单的工作示例来解释我的问题。

给定字符串:

$password1 = 'Uif4yQZUqmCWRbWFQtdizZ9/qwPDyVHSLiR19gc6oO7QjAK6PlT/rrylpJDkZaEUOSI5c85xNEVA6JnuBrhWJw=='; 
$password2 = 'Uif4yQZUqmCWRbWFQtdizZ9/qwPDyVHSLiR19gc6oO7QjAK6PlT/rrylpJDkZaEUOSI5c85xNEVA6JnuBrhWJw==';
$password3 = 'iV3pT5/JpPhIXKmzTe3EOxSfZSukpYK0UC55aKUQgVaCgPXYN2SQ5FMUK/hxuj6qZoyhihz2p+M2M65Oblg1jg==';

示例 1(按预期操作)

echo $password1 === $password2 ? 'True' : 'False'; // Output: True
echo equals($password1, $password2) ? 'True' : 'False'; // Output: True

示例 2(按预期操作)

echo $password1 === $password3 ? 'True' : 'False'; // Output: False
echo equals($password1, $password3) ? 'True' : 'False'; // Output: False

我读到了 Karp Rabin Algorithm但我不确定 equals() 函数是否代表Karp Rabin Algorithm ,总的来说,我不理解维基百科的文章。

另一方面,我读到equals() 函数可以防止暴力攻击,对吗?有人可以解释一下 equals() 的优势是什么吗?或者有人可以给我一个例子,其中 === 会失败,而 equals() 会正确工作,这样我就能理解其中的优势吗?

恒定时间算法是什么意思?我认为 constant-time 与实时无关,还是我错了?

最佳答案

这个函数只是一个普通的字符串比较函数。这不是拉宾卡普。这不是常数时间,它是线性时间,不管评论怎么说。它也不能防止暴力攻击。

工作原理:

  1. 如果正确的密码和用户提供的密码长度不同,使$result != 0
  2. 遍历用户提供的密码,将其每个字符与正确密码的相应字符异或(如果正确密码更短,则继续循环),然后按位或每个结果与 $result。

由于仅按位或使用,如果任何字符不同,$result 将为 != 0。需要步骤 1,否则,如果真实密码为“abc”,则用户输入“abca”将被接受。

为什么有时会用到这样的字符串比较函数

假设我们以通常的方式比较字符串,正确的密码是“bac”。我们还假设我可以精确测量完成密码检查需要多长时间

我(用户)尝试了 abc...它们不起作用。

然后,我尝试aa。该算法比较前 2 个字母 - ba,发现错误并返回 false。

我现在尝试使用 bb。该算法比较 bb,它们匹配,所以它继续到字母 #2,比较 ab,看错了,返回false。现在,由于我能够精确地计算算法的执行时间,我知道密码以“b”开头,因为第二次传递比第一次花费的时间更多 - 我知道第一个字母匹配。

所以我尝试了 babbbc……它们都失败了。

现在我检查baabbb,发现baa运行速度较慢,所以第二个字母是a。这样,一个字母一个字母地,我可以在 O(cN) 次尝试中确定密码,而不是 O(c^N) 的蛮力。

它通常并不像这个解释听起来那么令人担忧,因为攻击者不太可能将字符串比较计时到如此精确的程度。但有时它可以。

关于php - 关于恒定时间算法和字符串比较的解释,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18916072/

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