问题引入
如何比较两个字符串?
这还不简单 使用"=="或"==="判断相等不就可以了
好吧 既然都这么问了 这个问题肯定是有"陷阱"的
那么 "陷阱"在哪里呢?
通常 字符串比较的实现基于移位匹配
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);
}
此时 碰到任何不匹配 则直接退出返回比较结果
于是 代码循环的次数都不一样的 导致执行耗时也是不一样的
当然 由于现代计算机性能的提升 普通开发者很难体会到耗时的差异
上述 便是本文所要讨论的"时序攻击"
时序攻击
如何防范"时序攻击"呢?
哈希算法有如下两个特点
输出定长: 输入无论是普通密码还是大文件 输出长度都是固定的
相同输入的输出相同: 因此哈希算法可以通过输出的摘要校验输入数据的完整性
因此 我们可以
首先 使用哈希算法得到将要比较的字符串的哈希值
接着 比较两个哈希值的字符串
了解了上述原理 伪代码实现如下
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;
}