zoukankan      html  css  js  c++  java
  • hash_equals()函数

    本文同时发表在https://github.com/zhangyachen/zhangyachen.github.io/issues/92

    了解下hash_equals的概念:

    bool hash_equals ( string $known_string , string $user_string )
    比较两个字符串,无论它们是否相等,本函数的时间消耗是恒定的。
    
    本函数可以用在需要防止时序攻击的字符串比较场景中, 例如,可以用在比较 crypt() 密码哈希值的场景。
    

    上面提到了时序攻击,什么是时序攻击呢?引自如何通俗地解释时序攻击(timing attack)?
    中shotgun的回答:

    举一个最简单的计时攻击的例子,某个函数负责比较用户输入的密码和存放在系统内密码是否相同,如果该函数是从第一位开始比较,发现不同就立即返回,那么通过计算返回的速度就知道了大概是哪一位开始不同的,这样就实现了电影中经常出现的按位破解密码的场景。密码破解复杂度成千上万倍甚至百万千万倍的下降。

    而hash_equals的时间消耗是恒定的,也就防止了时序攻击。

    PHP 中的 == 和“隐式转换”

    <?php
    var_dump(md5('240610708') == md5('QNKCDZO'));   //true
    

    为什么会是true?
    md5('240610708') 的结果是:0e462097431906509019562988736854
    md5('QNKCDZO') 的结果是:0e830400451993494058024219903391

    在PHP中, 在使用 == 号时,如果比较一个数字和字符串或者比较涉及到数字内容的字符串,则字符串会被转换为数值并且比较按照数值来进行。
    

    php会将以0x开头的或者0e开头的并且后面都是数字的(^0ed*(,^0xd*))当成数字来处理。上面两个例子都被等效成了 0×10^0 ,所以相等。
    类似的还有

    var_dump('0x1234Ab' == '1193131');   //true
    

    为了防止此现象,需要使用===或者hash_equals函数来处理。

    误解
    var_dump(0 == "0e1111111");    //true
    var_dump("0" == "0e1111111");   //true
    

    之前一直认为输出结果是true false。但是实验发现两个都是true。原来php在将字符串转换成整数的条件不光是字符串和整数比较。还有当两个数字型字符串比较时,也会将两个字符串都转换成整数。

    引用网上一张图:
    image
    image
    image

  • 相关阅读:
    水库采样算法
    在Windows的控制台和Linux的终端中显示加载进度
    如何在普通用户权限cmd怎么使用命令行变为管理员权限
    MySql命令行无法显示中文
    MySql精简
    C语言中的数据类型转换函数
    关于C语言命令行参数问题
    postgres 基本操作
    简单的实现HTTP密码验证登陆
    filebeat+logstash配置
  • 原文地址:https://www.cnblogs.com/zhangyachen/p/8033358.html
Copyright © 2011-2022 走看看