我从我正在使用的加密库中找到了下面的比较函数(稍作修改)。我很好奇旁道攻击的潜在漏洞。具体来说,仅当被比较的字符在两个字符串的范围内时才进行字符比较。我怀疑这可能允许攻击者确定字符串长度。
也许这种差异太小而无法受到计时攻击,但我在下面尝试了一下。我基本上创建长度增加的字符串并与给定的初始字符串进行比较。我期望在第二个字符串变长之前和之后的比较时间可能会出现线性增长,但由于执行的操作不同,因此可能具有不同的斜率。
相反,我看到了下面的数据(注意被比较的字符串长度为 27 个字符)。任何关于为什么我不知道我在说什么的解释将不胜感激:)
一个小提示,我确实尝试过-O0,以防出现一些奇怪的优化问题。从这里我唯一能想到的就是开始深入研究生成的程序集。

#include <string.h>
#include <sys/time.h>
#include <stdio.h>
int CompareStrings(const char* s1, const char* s2) {
int eq = 1;
int s1_len = strlen(s1);
int s2_len = strlen(s2);
if (s1_len != s2_len) {
eq = 0;
}
const int max_len = (s2_len < s1_len) ? s1_len : s2_len;
// to prevent timing attacks, should check entire string
// don't exit after found to be false
int i;
for (i = 0; i < max_len; ++i) {
if (s1_len >= i && s2_len >= i && s1[i] != s2[i]) {
eq = 1;
}
}
return eq;
}
double time_diff(struct timeval x , struct timeval y) {
double x_ms , y_ms , diff;
x_ms = (double)x.tv_sec*1000000 + (double)x.tv_usec;
y_ms = (double)y.tv_sec*1000000 + (double)y.tv_usec;
diff = (double)y_ms - (double)x_ms;
return diff;
}
void test_with_length(char* str1, int n) {
char str2[n + 1];
struct timeval tp1;
struct timeval tp2;
int i;
for (i = 0; i < n; i++) {
str2[i] = 'a';
}
str2[n] = '\0';
gettimeofday(&tp1, NULL);
for (i = 0; i < 20000000; i++) {
CompareStrings(str1, str2);
}
gettimeofday(&tp2, NULL);
printf("%d %.01f\n", n, time_diff(tp1, tp2));
}
int main() {
char *str1 = "XXXXXXXXXXXXXXXXXXXXXXXXXXX";
int i = 0;
for (i = 1; i <= 100; i++) {
test_with_length(str1, i);
}
}