实施旁道定时攻击

时间:2018-06-09 18:36:17

标签: hmac macos timing-attack

我正在研究在HMAC上用C实现侧通道定时攻击的项目。我通过利用strcmp的时序优化计算十六进制编码标签和逐字节强制来实现这一点。因此,对于测试标记中的每个数字,我计算每个十六进制字符验证所需的时间。我获取与计算出的最大时间量相对应的十六进制字符,并推断它是标记中的正确字符并继续下一个字节。但是,strcmp的时机非常难以预测。虽然很容易看出比较两个相等的字符串和两个完全不同的字符串之间的时间差异,但是我很难找到使用我的测试字符串最多时间计算的字符串,当我比较的每个其他字符串非常相似时(仅相差1个字节)。

下面的changeByte方法接受customTag,它是到那个时间点计算的标记,并试图找到与索引相对应的正确字节。 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);

}

1 个答案:

答案 0 :(得分: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;