比较防范定时攻击的两个字节数组



我想写一个方法来比较两个字节数组,但我不想使用这些解决方案,因为我希望该方法能够抵御定时攻击。我的方法基本上看起来像:

static bool AreEqual(byte[] a1, byte[] a2)
{
bool result = true;
for (int i = 0; i < a1.Length; ++i)
{
if (a1[i] != a2[i])
result = false;
}
return result;
}

(假设a1a2具有相同的长度)。

我担心的是,如果result设置为false,那么一个足够智能的即时编译器可能会通过提前返回来优化这一点。

我已经检查了.NET 4.0.30319生成的JITted汇编代码,但它没有:

`bool结果=true;'00e00d1 bb01000000 mov ebx,1`int i=0;'00e000d6 33f6 xor esi,esi;在eax和dword ptr[ebp-10h]中存储"a1.Length"00e000d8 8b4104 mov eax,双字ptr[ecx+4]00e00db 8945f0 mov dword ptr[ebp-10h],eax;如果"a1.Length"为0,则跳转到"return result;"00e00de 85c0测试eax,eax00e00e0 7e18 jle 00e00fa`如果(a1[i]!=a2[i])'00e00e2 0fb6443108 movzx eax,字节ptr[ecx+esi+8]00e00e7 3b7704 cmp esi,双字ptr[edi+4]00e000 ea 7316 jae 00e010200e00ec 3a443708 cmp al,字节ptr[edi+esi+8]00e000f0 7402 je 00e000f4`result=false;'00e00f2 33db xor ebx,ebx`++我00e000f4 46包括在内;检查:`a1.Length>i'00e00f5 3975f0 cmp双字ptr[ebp-10h],esi00e00f8 7fe8 jg 00e00e2`返回结果;'00e00fa 8bc3 mov eax,ebx00e00fc 59弹出式ecx00e00fd 5b弹出ebx00e00fe 5e pop-esi00e00ff 5f pop edi00e01000 5天弹出ebp00e0101 c3 ret00e0102 e81f7a1772调用clr!CreateHistoryReader+0x8e97c(72f77b26)00e0107 cc int 300e0108 0000添加字节ptr[eax],al00e010a 0000添加字节ptr[eax],al00e010c 0000添加字节ptr[eax],al00e010e 0000添加字节ptr[eax],al…

然而,我认为这种情况在未来可能会改变。

有没有办法阻止JIT编译器优化这个方法?或者,有没有一个库函数可以让我使用,它可以专门检查两个字节数组的相等性,但可以抵抗定时攻击?

您可以将System.Runtime.CompilerServices命名空间的MethodImplAttribute-class与MethodImplOptions.NoOptimization选项一起使用,如下所示:

[MethodImpl(MethodImplOptions.NoOptimization)]
static bool AreEqual(byte[] a1, byte[] a2)
{
// ...
}

最新更新