0

我正在开发一个项目,在 HMAC 上用 C 语言实现侧信道定时攻击。我通过利用 strcmp 的时序优化来计算十六进制编码的标签并逐字节强制执行。因此,对于我的测试标签中的每个数字,我计算每个十六进制字符验证所需的时间。我采用与计算出的最高时间量相对应的十六进制字符,并推断它是标签中的正确字符并移至下一个字节。但是,strcmp 的时间非常难以预测。虽然很容易看出比较两个相等的字符串和两个完全不同的字符串之间的时间差异,但是当我比较的每个其他字符串非常相似时,我很难找到花费我的测试字符串最长时间来计算的字符(仅相差 1 个字节)。

下面的changeByte 方法接受customTag,这是已经计算到那个时间点的标签,并试图找到对应于index 的正确字节。changeByte 被调用 n 次,其中 n=标签的长度。hexTag 是一个全局变量,它是正确的标记。timeCompleted 存储在每个十六进制字符处计算 char 位置的 testTag 所用的平均时间。任何帮助将不胜感激,感谢您的宝贵时间。

// Checks if the index of the given byte is correct or not
void changeByte(unsigned char *k, unsigned char * m, unsigned char * algorithm, unsigned char * customTag, int index)
{
    long iterations=50000;
    // used for every byte sequence to test the timing
    unsigned char * tempTag = (unsigned char *)(malloc(sizeof (unsigned char)*(strlen(customTag)+1 ) ));
    sprintf(tempTag, "%s", customTag);
    int timeIndex=0;
    // stores the time completed for every respective ascii char
    double * timeCompleted = (double *)(malloc (sizeof (double) * 16));

    // iterates through hex char 0-9, a-f
    for (int i=48; i<=102;i++){
            if (i >= 58 && i <=96)continue;
            double total=0;
            for (long j=0; j<iterations; j++){
                    // calculates the time it takes to complete for every char in that position
                    tempTag[index]=(unsigned char)i;
                    struct rusage usage;
                    struct timeval start, end;
                    getrusage(RUSAGE_SELF, &usage);
                    start=usage.ru_stime;
                    for (int k=0; k<50000; k++)externalStrcmp(tempTag, hexTag); // this is just calling strcmp in another file
                    getrusage (RUSAGE_SELF, &usage);
                    end=usage.ru_stime;
}
                    double startTime=((double)start.tv_sec + (double)start.tv_usec)/10000;
                    double endTime=((double)end.tv_sec+(double)end.tv_usec)/10000;
                    total+=endTime-startTime;
            }
            double val=total/iterations;
            timeCompleted[timeIndex]=val;
            timeIndex++;                

    }
    // sets next char equal to the hex char corresponding to the index
    customTag[index]=getCorrectChar (timeCompleted);
    free(timeCompleted);
    free(tempTag);

}

// finds the highest time. The hex char corresponding with the highest time it took the
// verify function to complete is the correct one
unsigned char getCorrectChar(double * timeCompleted)
{
    double high =-1;
    int index=0;
    for (int i=0; i<16; i++){
            if (timeCompleted[i]>high){
                    high=timeCompleted[i];
                    index=i;
            }
    }
    return (index+48)<=57 ?(unsigned char) (index+48) : (unsigned char)(index+87);

}
4

1 回答 1

1

我不确定这是否是主要问题,但是您直接将秒添加到微秒,就好像 1us == 1s。当 startTime 和 endTime 的秒数不同时,它会给出错误的结果。usec 和 sec 之间的比例因子是 1 000 000 (thx zaph)。所以这应该更好地工作:

double startTime=(double)start.tv_sec + (double)start.tv_usec/1000000;
double endTime=(double)end.tv_sec + (double)end.tv_usec/1000000;
于 2018-06-10T14:41:16.953 回答