2014-10-27 9 views
7

मुझे कुछ कोड बनाए रखने के साथ कोई समस्या दिखाई दे रही है। नीचे दिए गए कोड में private static SHA1 सदस्य है (जो IDisposable है लेकिन चूंकि यह static है, इसे कभी अंतिम रूप देना नहीं चाहिए)।SHA1.ComputeHash क्यों कई धागे के साथ उच्च लोड के तहत विफल रहता है?

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 पर कॉल चुपचाप विफल हो सकता है (कितने क्रिप्टोग्राफिक संसाधन उपलब्ध हैं)? क्या यह एपडोमेन नीचे जा रहा है?

कोई अन्य सिद्धांत?

+0

क्या इस निपटान के साथ क्या करना है? इसके अलावा, कौन सा "SHA1" वर्ग है? –

+1

क्या आप वाकई कक्षा SHA1 थ्रेडसेफ है? क्या आप विफल होने पर पासवर्ड को पकड़ने में सक्षम हैं? – Rob

+0

@ जॉन सॉंडर्स, क्षमा करें आप सही हैं। इसका निपटान करने के लिए कुछ भी नहीं है। मैंने सोचा था कि सिस्टम पर फाइनलाइज़र। सुरक्षा। क्रिप्टोग्राफी .एचए 1 क्रिप्टो सेवा सेवा प्रदाता किसी भी तरह से ट्रिगर हो सकता है। http://msdn.microsoft.com/en-us/library/e7hyyd4e(v=vs.110).aspx – MvdD

उत्तर

23
HashAlgorithm आधार वर्ग

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

आप धागे अलग धागे कोशिश करते हैं और एक ही समय में एक ही उदाहरण पर ComputeHash फोन जहां के बीच इन कक्षाओं साझा नहीं करना चाहिए के लिए

प्रति the documentation के रूप में।

EDIT यह आपकी त्रुटि का कारण बन रहा है। नीचे दिए गए तनाव परीक्षण में एक ही हैश एल्गोरिदम उदाहरण पर ComputeHash को कॉल करने वाले एकाधिक थ्रेडों के कारण कई त्रुटियां उत्पन्न होती हैं। आपकी त्रुटि उनमें से एक है।

विशेष रूप से, मैं इस तनाव परीक्षण के साथ निम्न त्रुटियों को देखा है: निर्दिष्ट राज्य में उपयोग के लिए मान्य हैश नहीं:

  • System.Security.Cryptography.CryptographicException।
  • System.ObjectDisposedException: सुरक्षित संभाल

बंद कर दिया गया तनाव परीक्षण कोड नमूना:

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

उल्लेखनीय दुर्घटना, सुरक्षित हैंडल ठीक दिखता है। लेकिन निर्विवाद, अच्छा जवाब। –

+1

@ हंसपैसेंट। धन्यवाद। मुझे लगता है कि यह 'SHA1CryptoServiceProvider.Initialize' विधि हो सकता है, जो एक गैर थ्रेड सुरक्षित' निपटान 'प्रतीत होता है और फिर '_safeHashHandle' फ़ील्ड पर फिर से बना सकता है। –

+0

हेहे, बिज़ारो, आरंभ() को * हैश की गणना करने के बाद * कहा जाता है। किसी तरह की सुरक्षा चीज होनी चाहिए। आपको यह मिला। –

संबंधित मुद्दे