Сравнение двух байтовых массивов, защищающих от временных атак

Я хочу написать метод для сравнения двух байтовых массивов, но я не хочу использовать эти решения, потому что я хочу, чтобы метод был устойчивым к временным атакам. Мой метод по сути выглядит так:

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;
}

(с предположением, что a1 а также a2 имеют одинаковую длину).

Меня беспокоит то, что достаточно умный компилятор точно в срок может оптимизировать это, возвращаясь рано, если result всегда установлен в ложь.

Я проверил код сборки JITted, созданный в.NET 4.0.30319, и он не делает:

; `bool result = true; '
00e000d1 bb01000000 mov ebx, 1; `int i = 0; '
00e000d6 33f6 xor esi, esi; хранить `a1.Length'в eax и в dword ptr [ebp-10h]
00e000d8 8b4104          mov     eax,dword ptr [ecx+4]
00e000db 8945f0          mov     dword ptr [ebp-10h],eax; если `a1.Length'равно 0, тогда перейти к`return result;'
00e000de 85c0, тест Eax, Eax
00e000e0 7e18            jle     00e000fa; `if (a1[i]!= a2[i])'
00e000e2 0fb6443108      movzx   eax, ptr байта [ecx+esi+8]
00e000e7 3b7704          cmp     esi,dword ptr [edi+4]
00e000ea 7316            jae     00e00102
00e000ec 3a443708        cmp     al,byt ptr [edi+esi+8]
00e000f0 7402            je      00e000f4; `result = false;'
00e000f2 33 дБ xor     ebx,ebx; `++ я"
00e000f4 46 дюймов; проверьте: `a1.Length > i'
00e000f5 3975f0          cmp     dword ptr [ebp-10h],esi
00e000f8 7fe8            jg      00e000e2; `вернуть результат;'
00e000fa 8bc3            mov     eax,ebx
00e000fc 59              pop     ecx
00e000fd 5b              pop     ebx
00e000fe 5e              pop     esi
00e000ff 5f              pop     edi
00e00100 5d              pop     ebp
00e00101 c3              ret
00e00102 e81f7a1772 вызов clr!CreateHistoryReader+0x8e97c (72f77b26)
00e00107 куб. См. 3
00e00108 0000 добавить байт ptr [eax],al
00e0010a 0000 добавить байт ptr [eax],al
00e0010c 0000 добавить байт ptr [eax],al
00e0010e 0000 добавить байт ptr [eax],al
...

Тем не менее, я думаю, что это может измениться в будущем.

Есть ли способ помешать JIT-компилятору оптимизировать этот метод? В качестве альтернативы, есть ли библиотечная функция, которую я могу использовать, которая специально проверяет двухбайтовые массивы на равенство, но устойчива к временным атакам?

1 ответ

Решение

Вы можете использовать MethodImplAttribute -Класс System.Runtime.CompilerServices пространство имен с MethodImplOptions.NoOptimization вариант как этот:

[MethodImpl(MethodImplOptions.NoOptimization)]
static bool AreEqual(byte[] a1, byte[] a2)
{
    // ...
}
Другие вопросы по тегам