【发布时间】:2014-12-22 22:17:27
【问题描述】:
我发现我维护的一些代码存在问题。下面的代码有一个private static SHA1 成员(这是一个IDisposable,但因为它是static,所以它永远不会被最终确定)。然而,在压力下,这段代码会抛出一个异常,表明它已被关闭:
Caught exception. Safe handle has been closed"
Stack trace: Call stack where exception was thrown
at System.Runtime.InteropServices.SafeHandle.DangerousAddRef(Boolean& success)
at System.Security.Cryptography.Utils.HashData(SafeHashHandle hHash, Byte[] data, Int32 cbData, Int32 ibStart, Int32 cbSize)
at System.Security.Cryptography.Utils.HashData(SafeHashHandle hHash, Byte[] data, Int32 ibStart, Int32 cbSize)
at System.Security.Cryptography.HashAlgorithm.ComputeHash(Byte[] buffer)
有问题的代码是:
internal class TokenCache
{
private static SHA1 _sha1 = SHA1.Create();
private string ComputeHash(string password)
{
byte[] passwordBytes = UTF8Encoding.UTF8.GetBytes(password);
return UTF8Encoding.UTF8.GetString(_sha1.ComputeHash(passwordBytes));
}
我的问题显然是什么可能导致这个问题。对SHA1.Create 的调用能否静默失败(有多少加密资源可用)?会不会是 appdomain 宕机了?
还有其他理论吗?
【问题讨论】:
-
这与 Dispose 有什么关系?另外,那是哪个“SHA1”类?
-
你确定 SHA1 类是线程安全的吗?当密码失败时,你能抓住被哈希的密码吗?
-
@John Saunders,对不起,你是对的。这与 Dispose 无关。我认为 System.Security.Cryptography.SHA1CryptoServiceProvider 上的终结器可能已被某种方式触发。 msdn.microsoft.com/en-us/library/e7hyyd4e(v=vs.110).aspx
-
@user18044 我刚刚在本地(10,000)个随机哈希值上进行了压力测试。它工作得很好。将其更改为并行会导致您收到完全相同的错误(安全手柄已关闭)。我很确定这是因为在某个地方,您的应用程序是线程化的。
-
@user18044 下面重现了您的错误:
var strings = Enumerable.Range(1,10000).Select(r => Guid.NewGuid().ToString()).ToList(); Parallel.ForEach(strings, s => { ComputeHash(s).Dump(); });使用foreach,但是,不会
标签: c# sha stress-testing finalizer