好吧,我想哈希一个密码,我看看ASP.net身份在Microsoft.AspNet.Identity.Crypto
类中是怎么做的,我来了这个函数(用于比较2个密码哈希) :
[MethodImpl(MethodImplOptions.NoOptimization)]
private static bool ByteArraysEqual(byte[] a, byte[] b)
{
if (object.ReferenceEquals(a, b))
{
return true;
}
if (((a == null) || (b == null)) || (a.Length != b.Length))
{
return false;
}
bool flag = true;
for (int i = 0; i < a.Length; i++)
{
flag &= a[i] == b[i];
}
return flag;
}
这是反射器输出的直接复制......
现在我的问题是, NoOptimization属性对于有什么好处,为什么它应该存在(如果我删除它会发生什么)?对我来说,它看起来像一个默认的Equals()实现,直到for
- 循环。
我试着看一下IL,但这对我来说都是胡说八道:/
答案 0 :(得分:17)
如果“智能”编译器在发现不匹配时将该函数转换为返回false
的函数,则可能使使用此函数的代码容易受到“定时攻击” - 攻击者可以想象找出字符串中第一个不匹配的位置取决于函数返回的时间。
实际上,这不仅仅是科幻小说,即使它看起来像是这样。即使有了互联网,你也可以采取一大堆样本,并使用一些统计数据来弄清楚如果你猜测实现是否会发生短路会发生什么。
答案 1 :(得分:2)
也可能存在 JIT编译器
的情况我遇到过优化方法与非优化方法不同的情况。 (我相信这是上面的案例A)。将该方法声明为
[MethodImpl(MethodImplOptions.NoOptimization)]
解决了这个问题。