我在问自己,在asp.net页面的代码后台使用包含HMACSHA1实例的静态(共享)变量是否会有危险。问题是,当处理同一asp.net页面上的多个同时请求时,所有ASP.Net工作进程线程将使用相同的HMACSHA1实例。由ComputeHash()使用/修改的所有(HMACSHA1)实例和ComputeHash()-method变量是否会被所有线程共享(=可以修改)?!这个假设是正确的吗?因此,无法保证ComputeHash的返回值是正确的?!?!因此,我不允许在所有ASP.NET线程上使用静态/共享的HMACSHA1实例。
我只是想知道你对这个问题的看法。
解决这个问题的唯一方法是在ComputeHash()-method中设置关键路径等。但这“超出了我们的能力范围”..
致敬,克里斯
发布于 2009-02-20 14:22:02
散列算法是确定性的,它们必须每次为给定的输入返回相同的散列。
只要你每次都使用相同的键,那么就没有必要让它们成为静态的。但是,如果使用无参数构造函数构造HMACSHA1实例,那么它会生成一个随机密钥。您应该从KeyValue属性中获取随机值,并将其与散列一起存储。
使用静态实例绝对是危险的。如果Thread1设置要计算的值,然后Thread2在Thread1调用ComputerHash()之前设置该值,那么Thread1将获得Thread2值的散列。如果两个线程中的任何一个正在设置密钥,都会发生同样的情况。
发布于 2011-11-14 07:27:03
当我在一个四核的HT上运行8或16个执行哈希计算的并行任务时,我刚刚从SHA256Cng.ComputeHash得到了一个未知的密码异常。
围绕ComputeHash添加锁定语义解决了这个问题--所以至少看起来SHA256Cng版本不是线程安全的。
发布于 2014-11-11 15:21:29
值得知道是,KeyedHashAlgorithm.ComputeHash()不是线程安全的,因为它为相同的KeyedHashAlgorithm.Key提供了不确定的结果。
在我的例子中,我想缓存KeyedHashAlgorithm,因为我的KeyedHashAlgorithm.Key总是相同的,以便从客户端验证的真实性。我意识到ComputeHash()并不一致,可能是它在KeyedHashAlgorithm实例中缓存了内部变量。我应该为每个线程、ThreadStatic或ThreadLocal缓存实例。这就是测试:
静态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);与每个线程的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);此代码可用于测试其他函数的“线程安全”结果。希望这能对其他人有所帮助。
https://stackoverflow.com/questions/569683
复制相似问题