【问题标题】:comparison of random_bytes fails when values match当值匹配时,random_bytes 的比较失败
【发布时间】:2017-07-17 09:59:27
【问题描述】:

这里简短而有趣。我可能在这里遇到了一些奇怪的事情,但我现在已经浪费了几个小时,无法找出问题所在。

我有一个产生随机数的函数,就像这样。目前它不是很复杂,但更多的是对我来说新概念的实验。我使用 random_bytes 作为 PHP7+ 的 mcrypt_create_iv 的自然继承者:

$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_dumpshows 都是长度相等的字符串,但由于某种原因,它们不可比较。这两个值看起来很匹配。

if(hash_equals($nonce, $nonce))

等于 true(如您所料),所以我只能假设其中一个值正在被更改,无论是通过 $_POST 还是通过我的检索函数(实际上只是从会话中读取) .

如果有任何帮助/建议,我将不胜感激 - 我要么忽略了一些明显的事情,要么对此缺乏经验。

【问题讨论】:

    标签: php php-7 nonce


    【解决方案1】:

    并非所有随机字节值都直接在 HTML 中有效。如果字符串包含常规 ascii 字母和数字序列 ([0-9a-zA-z]) 之外的值,如果您不为 HTML 上下文转义它,任何事情都可能发生。如有必要,您可以使用 htmlspecialchars 转义值,或者使用随机字节的哈希或 base64 编码版本。

    一个很好的例子是如果" 的ascii 值包含在16 个随机字节中,您的HTML 属性将提前结束。 HTML 不太喜欢控制序列(低 ascii 字符)或当前编码之外的字母(如果是 UTF-8,则在跨多个字节查看时,任何高于 127 的值都需要是有效的 UTF-8 代码点)。

    【讨论】:

    • 非常好 - 我已将我的函数修改为 $token = base64_encode(random_bytes(16));,现在可以使用了。我知道这很简单,但你仍然是一个传奇!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多