2014-10-27 15 views
7

Baktığım bazı kodlarla ilgili bir sorun görüyorum. Aşağıdaki kod private static SHA1 üyesine sahiptir (IDisposable, ancak static olduğundan, hiçbir zaman sonlandırılmış olmamalıdır). Söz konusuSHA1.ComputeHash, birçok iş parçacığıyla neden yüksek yük altında başarısız oluyor?

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) 

kodudur:

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)); 
    } 

Sorum bu soruna neden ne olabilir besbelli Ancak stres altında bu kod kapatıldıktan anlaşılacağı bir istisna atar. SHA1.Create numaralı çağrı sessizce başarısız olabilir (kaç tane şifreleme kaynağı kullanılabilir)? Bu, appdomain inişinden kaynaklanabilir mi?

Başka teoriler var mı? HashAlgorithm temel sınıf

Any public static (Shared in Visual Basic) members of this type are thread safe. Any instance members are not guaranteed to be thread safe.

Farklı ipler denemek ve aynı zamanda aynı örneğinde ComputeHash çağrı konuları arasında bu ders paylaşması gerektiğini için the documentation gereğince

+0

Bunun imha ediniz ilgisi var? Ayrıca, hangi "SHA1" sınıfı bu? –

+1

SHA1 sınıfının threadafe olduğundan emin misiniz? Başarısız olduğunda karma olan şifreyi yakalayabilir misiniz? – Rob

+0

@John Saunders, üzgünüz, haklısın. Bunun Dispose ile ilgisi yok. System.Security.Cryptography.SHA1CryptoServiceProvider'daki sonlaştırıcının bir şekilde tetiklenmiş olabileceğini düşündüm. http://msdn.microsoft.com/en-us/library/e7hyyd4e(v=vs.110).aspx – MvdD

cevap

23

.

EDIT Bu, hata iletisine neden oluyor. Aşağıdaki stres testi, aynı karma algoritma örneğinde ComputeHash çağrılan birden fazla iş parçacığı nedeniyle çeşitli hatalar vermektedir. Senin hatan onlardan biri.

Özellikle, bu stres testi ile aşağıdaki hatalar gördük: Belirtilen durumda kullanım için geçerli karma değil:

  • System.Security.Cryptography.CryptographicException.
  • System.ObjectDisposedException: Güvenli kolu

kapatıldı Stres testi kod örneği:

const int threadCount = 2; 
var sha1 = SHA1.Create(); 
var b = new Barrier(threadCount); 
Action start =() => { 
        b.SignalAndWait(); 
        for (int i = 0; i < 10000; i++) 
        { 
         var pwd = Guid.NewGuid().ToString(); 
         var bytes = Encoding.UTF8.GetBytes(pwd); 
         sha1.ComputeHash(bytes); 
        } 
       }; 
var threads = Enumerable.Range(0, threadCount) 
         .Select(_ => new ThreadStart(start)) 
         .Select(x => new Thread(x)) 
         .ToList(); 
foreach (var t in threads) t.Start(); 
foreach (var t in threads) t.Join(); 
+0

Dikkat çeken yanlış kullanım, güvenli tutma yeri iyi görünüyor. Ama inkar edilemez, iyi cevap. –

+1

@HansPassant. Teşekkür ederim. Ben thread olmayan güvenli bir 'Dispose 'yapmak ve daha sonra' _safeHashHandle' alanında yeniden oluşturmak için görünen SHA1CryptoServiceProvider.Initialize' yöntemi olabilir sanırım. –

+0

Hehe, bizarro, Initialize() isminden * sonra * denir. Bir çeşit güvenlik görevi olmalı. Anladın. –

İlgili konular