当值匹配时 random_bytes 的比较失败
comparison of random_bytes fails when values match
这里简短但有趣。我可能在这里遇到了一些奇怪的事情,但我现在已经失去了几个小时,无法找出问题所在。
我有一个生成随机数的函数,就像这样。目前它不是很复杂,但更像是对一个对我来说很新的概念的实验。我使用 random_bytes 作为 mcrypt_create_iv
的自然继承者 for PHP7+:
$token = random_bytes(16);
然后像这样存储:
$session->add('nonce',$token);
(which is essentially....)
$_SESSION[$var] = $val;
同时在我的表单中使用,如下所示:
<input name="token" type="hidden" value="<?=$token?>">
表单提交并通过一些验证等。作为其中的一部分,我检索了两个值:
$token = $_POST['token'];
$nonce = $session->get('nonce');
然后我有一个进一步执行的验证点 - 仅当两个值匹配时才继续。问题是,我实际上无法让他们验证。这些当前输出都不为真:
if(hash_equals($nonce, $token))
if($nonce === $token)
var_dump
显示两者都是等长的字符串,但由于某些原因它们不可比较。两个值看起来都匹配。
if(hash_equals($nonce, $nonce))
等于 true(如您所料),所以我只能假设其中一个值在过程中发生了变化,通过 $_POST
或通过我的检索函数(字面上只是读取来自会话)。
我会很感激任何 help/suggestions - 我要么忽略了一些明显的东西,要么对此太缺乏经验。
并非所有随机字节值都直接在 HTML 中有效。如果字符串包含超出常规 ascii 字母和数字序列 ([0-9a-zA-z]
) 的值,如果您不针对 HTML 上下文对其进行转义,则任何事情都可能发生。如有必要,您可以使用 htmlspecialchars
对值进行转义,或者改用随机字节的哈希或 base64 编码版本。
一个很好的例子是,如果 "
的 ascii 值包含在 16 个随机字节中,您的 HTML 属性将提前结束。 HTML 不太喜欢控制序列(低 ascii 字符)或当前编码之外的字母(如果是 UTF-8,则在跨多个字节查看时,任何高于 127 的值都需要是有效的 UTF-8 代码点).
这里简短但有趣。我可能在这里遇到了一些奇怪的事情,但我现在已经失去了几个小时,无法找出问题所在。
我有一个生成随机数的函数,就像这样。目前它不是很复杂,但更像是对一个对我来说很新的概念的实验。我使用 random_bytes 作为 mcrypt_create_iv
的自然继承者 for PHP7+:
$token = random_bytes(16);
然后像这样存储:
$session->add('nonce',$token);
(which is essentially....)
$_SESSION[$var] = $val;
同时在我的表单中使用,如下所示:
<input name="token" type="hidden" value="<?=$token?>">
表单提交并通过一些验证等。作为其中的一部分,我检索了两个值:
$token = $_POST['token'];
$nonce = $session->get('nonce');
然后我有一个进一步执行的验证点 - 仅当两个值匹配时才继续。问题是,我实际上无法让他们验证。这些当前输出都不为真:
if(hash_equals($nonce, $token))
if($nonce === $token)
var_dump
显示两者都是等长的字符串,但由于某些原因它们不可比较。两个值看起来都匹配。
if(hash_equals($nonce, $nonce))
等于 true(如您所料),所以我只能假设其中一个值在过程中发生了变化,通过 $_POST
或通过我的检索函数(字面上只是读取来自会话)。
我会很感激任何 help/suggestions - 我要么忽略了一些明显的东西,要么对此太缺乏经验。
并非所有随机字节值都直接在 HTML 中有效。如果字符串包含超出常规 ascii 字母和数字序列 ([0-9a-zA-z]
) 的值,如果您不针对 HTML 上下文对其进行转义,则任何事情都可能发生。如有必要,您可以使用 htmlspecialchars
对值进行转义,或者改用随机字节的哈希或 base64 编码版本。
一个很好的例子是,如果 "
的 ascii 值包含在 16 个随机字节中,您的 HTML 属性将提前结束。 HTML 不太喜欢控制序列(低 ascii 字符)或当前编码之外的字母(如果是 UTF-8,则在跨多个字节查看时,任何高于 127 的值都需要是有效的 UTF-8 代码点).