HMACSHA1.ComputeHash()线程安全问题

4 asp.net sha1 hmac

我问自己,在asp.net页面的代码隐藏中使用包含HMACSHA1实例的静态(共享)变量是否有危险.问题是当在同一个asp.net页面上处理多个同时请求时,所有asp.net worker-process'线程将使用相同的HMACSHA1实例.all(HMACSHA1)instance-和ComputeHash() - 由ComputeHash()使用/修改的方法变量将被所有线程共享(=可以修改)?这个假设是正确的吗?因此,ComputeHash的返回值不能保证是正确的?!?!因此我不允许在所有的asp.net-threads上使用静态/共享HMACSHA1实例.

我只是想知道你对这个问题的看法.

解决这个问题的唯一方法就是在ComputeHash()方法中使用关键路径等.但那是"我们无法接触到的"..

问候,克里斯

小智 8

我在SHA256Cng.ComputeHash中获得了一个未知的加密异常,当在四核HT cpu上运行8或16个并行任务时,其中包括执行散列计算.

在ComputeHash周围添加锁定语义解决了这个问题 - 所以看起来至少SHA256Cng版本不是线程安全的.


blo*_*art 5

散列算法是确定性的,它们必须每次都为给定的输入返回相同的散列.

只要您每次使用相同的密钥,就不需要将它们设置为静态.但是,如果您使用无参数构造函数构造HMACSHA1实例,则它会生成随机密钥.您应该从KeyValue属性中获取随机值并将其与散列一起存储.

使用静态实例肯定是危险的.如果Thread1设置要计算的值,然后Thread2在Thread1调用ComputerHash()之前设置该值,则Thread1将获取Thread2值的散列值.如果任一线程正在设置密钥,则会发生相同的情况.


Cal*_*aNN 5

值得一提的是,这KeyedHashAlgorithm.ComputeHash()不是线程安全的,因为它为相同的KeyedHashAlgorithm.Key.

就我而言,我想缓存 KeyedHashAlgorithm,因为我KeyedHashAlgorithm.Key总是从客户端验证真实性。我意识到这ComputeHash()是不一致的,可能它将内部变量缓存到KeyedHashAlgorithm实例中。我应该缓存每个线程ThreadStaticThreadLocal. 这是测试:

静态KeyedHashAlgorithm给出不一致的结果:

var kha = KeyedHashAlgorithm.Create("HMACSHA256");
kha.Key = Encoding.UTF8.GetBytes("key");
Action comp = () =>
{
    var computed = kha.ComputeHash(Encoding.UTF8.GetBytes("message"));
    Console.WriteLine(Convert.ToBase64String(computed));
};
Parallel.Invoke(comp, comp, comp, comp, comp, comp, comp, comp);
Run Code Online (Sandbox Code Playgroud)

KeyedHashAlgorithm每个线程相比:

ThreadLocal<KeyedHashAlgorithm> tl= new ThreadLocal<KeyedHashAlgorithm>(() =>
{
    var kha = KeyedHashAlgorithm.Create("HMACSHA256");
    kha.Key = Encoding.UTF8.GetBytes("key");
    return kha;
});
Action comp = () =>
{
    var computed = tl.Value.ComputeHash(Encoding.UTF8.GetBytes("message"));
    Console.WriteLine(Convert.ToBase64String(computed));
};
Parallel.Invoke(comp, comp, comp, comp, comp, comp, comp, comp);
Run Code Online (Sandbox Code Playgroud)

此代码可用于测试其他函数的“线程安全”结果。希望这会帮助其他人。