首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >HMACSHA1.ComputeHash()线程安全问题

问HMACSHA1.ComputeHash()线程安全问题
EN

Stack Overflow用户
提问于 2009-02-20 14:12:38
回答 4查看 4.9K关注 0票数 7

我在问自己,在asp.net页面的代码后台使用包含HMACSHA1实例的静态(共享)变量是否会有危险。问题是,当处理同一asp.net页面上的多个同时请求时,所有ASP.Net工作进程线程将使用相同的HMACSHA1实例。由ComputeHash()使用/修改的所有(HMACSHA1)实例和ComputeHash()-method变量是否会被所有线程共享(=可以修改)?!这个假设是正确的吗?因此,无法保证ComputeHash的返回值是正确的?!?!因此,我不允许在所有ASP.NET线程上使用静态/共享的HMACSHA1实例。

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

解决这个问题的唯一方法是在ComputeHash()-method中设置关键路径等。但这“超出了我们的能力范围”..

致敬,克里斯

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2009-02-20 14:22:02

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

只要你每次都使用相同的键,那么就没有必要让它们成为静态的。但是,如果使用无参数构造函数构造HMACSHA1实例,那么它会生成一个随机密钥。您应该从KeyValue属性中获取随机值,并将其与散列一起存储。

使用静态实例绝对是危险的。如果Thread1设置要计算的值,然后Thread2在Thread1调用ComputerHash()之前设置该值,那么Thread1将获得Thread2值的散列。如果两个线程中的任何一个正在设置密钥,都会发生同样的情况。

票数 6
EN

Stack Overflow用户

发布于 2011-11-14 07:27:03

当我在一个四核的HT上运行8或16个执行哈希计算的并行任务时,我刚刚从SHA256Cng.ComputeHash得到了一个未知的密码异常。

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

票数 9
EN

Stack Overflow用户

发布于 2014-11-11 15:21:29

值得知道是,KeyedHashAlgorithm.ComputeHash()不是线程安全的,因为它为相同的KeyedHashAlgorithm.Key提供了不确定的结果。

在我的例子中,我想缓存KeyedHashAlgorithm,因为我的KeyedHashAlgorithm.Key总是相同的,以便从客户端验证的真实性。我意识到ComputeHash()并不一致,可能是它在KeyedHashAlgorithm实例中缓存了内部变量。我应该为每个线程、ThreadStatic或ThreadLocal缓存实例。这就是测试:

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

代码语言:javascript
复制
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相比:

代码语言:javascript
复制
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);

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

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/569683

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档