Web安全 之 时序攻击

2018-04-28  本文已影响226人  诺之林

问题引入

如何比较两个字符串?

这还不简单 使用"=="或"==="判断相等不就可以了

好吧 既然都这么问了 这个问题肯定是有"陷阱"的

那么 "陷阱"在哪里呢?

通常 字符串比较的实现基于移位匹配

int
strcmp(const char *s1, const char *s2)
{
    for ( ; *s1 == *s2; s1++, s2++)
    if (*s1 == '\0')
        return 0;
    return ((*(unsigned char *)s1 < *(unsigned char *)s2) ? -1 : +1);
}

上述源码引自Apple Open Source

此时 碰到任何不匹配 则直接退出返回比较结果

于是 代码循环的次数都不一样的 导致执行耗时也是不一样的

当然 由于现代计算机性能的提升 普通开发者很难体会到耗时的差异

上述 便是本文所要讨论的"时序攻击"

关于"时序攻击"的学术定义 可以参考Timing attack

时序攻击

如何防范"时序攻击"呢?

这里 我们可以回忆一下PHP开发 之 摘要和签名所讨论的哈希算法

哈希算法有如下两个特点

输出定长: 输入无论是普通密码还是大文件 输出长度都是固定的

相同输入的输出相同: 因此哈希算法可以通过输出的摘要校验输入数据的完整性

因此 我们可以

首先 使用哈希算法得到将要比较的字符串的哈希值

接着 比较两个哈希值的字符串

了解了上述原理 伪代码实现如下

bool
hash_equals(const char *s1, const char *s2)
{
    const char *h1 = hash(s1);
    const char *h2 = hash(s2);
    return strcmp(h1, h2) == 0 ? true : false;
}

常见编程语言都实现了原生的hash_equals方法 例如: PHP实现可以参考hash_equals

参考

上一篇 下一篇

猜你喜欢

热点阅读