2014-09-30 4 views
11

मैं निम्नलिखित उपयोग के मामले है:क्या एक .NET हैश एल्गोरिदम की प्रतिलिपि बनाना संभव है (बार-बार वृद्धिशील हैश परिणाम के लिए)?

  • पढ़ें n एक फ़ाइल से बाइट्स
  • कंप्यूट (MD5) इन n बाइट्स के लिए हैश
  • पढ़ें फ़ाइल
  • कंप्यूट (MD5) हैश से अगले मीटर बाइट्स फ़ाइल के लिए एन + एम बाइट्स

बढ़ती हुई फाइल को समस्या नहीं है, just call TransformBlock and TransformFinalBlock

समस्या यह है कि मैं डेटा इसकी शुरुआत बाइट्स प्रयोग करती है, के कई हैश की जरूरत है, लेकिन उसके बाद मैं TransformFinalBlock कहा जाता है पहले n बाइट्स मैं एक ही वस्तु के साथ हैश करने के लिए जारी नहीं रख सकते की Hash पढ़ सकते हैं और एक नया एक की जरूरत है।

समस्या के लिए सर्च कर रहे हैं, मैंने देखा कि दोनों Python के साथ-साथ OpenSSL वास्तव में इस उद्देश्य के लिए एक हैशिंग वस्तु कॉपी करने के लिए एक विकल्प है: एक प्रति वापसी

hash.copy()

(हैश ऑब्जेक्ट का "क्लोन")। यह का उपयोग स्ट्रिंग्स के डायजेस्ट को कुशलतापूर्वक गणना करने के लिए किया जा सकता है जो एक सामान्य प्रारंभिक सबस्ट्रिंग साझा करते हैं।

 

EVP_MD_CTX_copy_ex() संदेश बाहर करने के लिए से राज्य को पचाने कॉपी करने के लिए इस्तेमाल किया जा सकता। यह उपयोगी है अगर बड़ी मात्रा में डेटा को धोया जाना है जो पिछले कुछ बाइट्स में भिन्न है। इस फ़ंक्शन को कॉल करने से पहले प्रारंभ करना होगा।

सर्च कर रहे हैं के रूप में मैं, मैं भीतर स्टॉक सी # HashAlgorithm कुछ भी है कि अनुमति होगी मुझे प्रभावी रूप से Clone() == इस तरह के एक वस्तु कॉपी करने के लिए से पहले अपने TransformFinalBlock विधि बुला नहीं मिल सकता है हो सकता है - और बाद में हैश करने के लिए जारी रखने के लिए क्लोन के साथ शेष डेटा।

मुझे C# reference implementation for MD5 मिला जो क्लोनिंग (*) का समर्थन करने के लिए छोटे से अनुकूलित किया जा सकता है लेकिन कोडबेस में ऐसी चीज पेश करने के बजाय वहां क्या है, इसका उपयोग करना पसंद करता है।

(*) दरअसल, जहाँ तक मैं समझता हूँ, किसी भी हैशिंग एल्गोरिथ्म (के रूप में एन्क्रिप्शन/डिक्रिप्शन के खिलाफ) मैं जाँच करने के लिए परेशान किया है तुच्छता copyable क्योंकि सभी राज्य इस तरह के एक एल्गोरिथ्म है एक का एक रूप है है डाइजेस्ट।

तो क्या मुझे यहां कुछ याद आ रहा है या मानक सी #/.NET इंटरफ़ेस वास्तव में हैश ऑब्जेक्ट की प्रतिलिपि बनाने का तरीका नहीं प्रदान करता है?


एक और डेटा बिंदु:

CryptDuplicateHash समारोह बनाने के लिए इस्तेमाल किया जा सकता है:

माइक्रोसॉफ्ट के खुदcrypto services के लिए देशी एपीआई एक समारोह CryptDuplicateHash, जो राज्य के डॉक्स, बोली है एक ही सामग्री के साथ शुरू होने वाली दो अलग-अलग सामग्री के अलग हैंश ।

विंडोज एक्सपी के आसपास के आसपास थे। : - |


नोट wrt। एमडी 5: उपयोग का मामला क्रिप्टोग्राफिक रूप से संवेदनशील नहीं है। बस विश्वसनीय फ़ाइल चेकसमिंग।

+0

इसके साथ एक मुद्दा मामूली रूप से क्लोनेबल नहीं है, कुछ कक्षाएं मूल संसाधनों का उपयोग कर सकती हैं या हैंडल के साथ विशेष हार्डवेयर को कॉल कर सकती हैं। उन प्रकार के वर्ग क्लोन के लिए आसान नहीं होगा। –

+0

@ स्कॉट - धन्यवाद। हाँ मुझे लगता है कि कुछ कक्षाएं हो सकती हैं। फिर भी, जो * * नहीं *, एमडी 5 की तरह, वास्तव में क्लोनबल होना चाहिए। तो कोई रास्ता नहीं है? –

+0

ऐसा लगता है कि अगर आप एक उथली प्रतिलिपि भी चाहते हैं तो आपको पूरी चीज को फिर से बनाना होगा और इसे स्वयं बनाना होगा। –

उत्तर

3

विलाप

स्टॉक नेट पुस्तकालय इस अनुमति नहीं है। उदास।वैसे भी, वहाँ विकल्प के एक जोड़े हैं:

  • MD5Managed pure .NET ("डिफ़ॉल्ट" MD5 आरएसए लाइसेंस)
  • ClonableHash कि (PInvoke के माध्यम से एमएस क्रिप्टो एपीआई कुछ निकालने काम की आवश्यकता हो सकती लपेटता है कि Org.Mentalis नाम स्थान है, लेकिन से लाइसेंस अनुमोदक है)

यह भी संभव है करने के लिए उदाहरण के लिए एक C++/CLI आवरण में एक C++ implementation लपेट - प्रारंभिक परीक्षण से पता चला है कि इस तरह से सामान्य नेट पुस्तकालय की तुलना में तेजी हो रहा है, लेकिन नहीं लेते इस पर मेरा शब्द।


के बाद से, मैं यह भी लिखा है/एक सी ++ आधारित समाधान अपने आप को अनुकूलित: https://github.com/bilbothebaggins/md5cpp

क्योंकि आवश्यकताएं बदल यह उत्पादन में नहीं गया है, लेकिन यह एक अच्छा व्यायाम था और मैं यह सोचना पसंद काफी अच्छी तरह से काम करता है। (इसके अलावा शुद्ध सी # कार्यान्वयन नहीं है।)

4

मुझे एहसास है कि यह वही नहीं है जो आप पूछ रहे हैं, लेकिन यदि यह समस्या से मेल खाता है तो आप इसे एक वैकल्पिक दृष्टिकोण हल करने की कोशिश कर रहे हैं जो आपको & समान स्ट्रीमिंग प्रदर्शन विशेषताओं की गारंटी देता है। मैंने इसे अतीत में सर्वर-टू-सर्वर फ़ाइल ट्रांसफर प्रोटोकॉल के लिए उपयोग किया है जहां प्रेषक/रिसीवर हमेशा उपलब्ध/विश्वसनीय नहीं थे। अनुमोदित, मैं तार के दोनों किनारों पर कोड पर नियंत्रण था जो मुझे एहसास है कि आप नहीं कर सकते हैं। उस स्थिति में, कृपया अनदेखा करें ;-)

मेरा दृष्टिकोण 1 हैश एल्गोरिदम स्थापित करना था जो पूरी फ़ाइल के साथ निपटाया गया था और फ़ाइल के फिक्स्ड-साइज्ड ब्लॉक के लिए दूसरा एक - रोलिंग हैश नहीं (आपकी समस्या से बचाता है), लेकिन स्टैंडअलोन हैश। तो कल्पना करें कि 1034 एमबी (1 जीबी + 10 एमबी) फ़ाइल तार्किक रूप से 32 एमबी ब्लॉक में विभाजित है। प्रेषक ने फाइल लोड किया, ट्रांसफॉर्मब्लॉक को फ़ाइल-स्तर और ब्लॉक-स्तर हैश एल्गोरिदम दोनों पर एक ही समय में कॉल किया। जब यह 32 एमबी के अंत तक पहुंच गया, तो इसे ब्लॉक-स्तर एक पर ट्रांसफॉर्मफिनलब्लॉक कहा जाता है, उस ब्लॉक के लिए हैश रिकॉर्ड किया गया है, और अगले ब्लॉक के लिए एक नया हैश एल्गोरिदम बनाया/बनाया है। जब यह फ़ाइल के अंत तक पहुंच गया तो इसे फ़ाइल पर ट्रांसफॉर्मफिनलब्लॉक कहा जाता है- और ब्लॉक-स्तर हैशर। अब प्रेषक के पास स्थानांतरण के लिए 'योजना' थी जिसमें फ़ाइल नाम, फ़ाइल आकार, फ़ाइल हैश, और ऑफसेट, लंबाई, और प्रत्येक ब्लॉक का हैश शामिल था।

यह रिसीवर को योजना भेजता है, जो या तो एक नई फ़ाइल के लिए स्थान आवंटित करता है (फ़ाइल लंबाई% ब्लॉक आकार यह बताता है कि अंतिम ब्लॉक 32 एमबी से छोटा है) या मौजूदा फ़ाइल खोला गया है। अगर फ़ाइल पहले से मौजूद थी, तो उसी आकार के ब्लॉक के हैश की गणना करने के लिए यह वही एल्गोरिदम चला गया। योजना के खिलाफ किसी भी विसंगति ने प्रेषक से उन ब्लॉकों के लिए केवल पूछने के लिए कहा (यह अभी तक हस्तांतरित ब्लॉक/सभी 0 और भ्रष्ट ब्लॉक के लिए जिम्मेदार नहीं होगा)। ऐसा करने के लिए कुछ भी नहीं छोड़ा गया जब तक यह एक लूप में काम नहीं करता (सत्यापित करें, ब्लॉक के लिए पूछें)। फिर उसने योजना के खिलाफ फ़ाइल-स्तर हैश की जांच की। यदि फ़ाइल-स्तर हैश अमान्य था लेकिन ब्लॉक-स्तरीय हैंश सभी मान्य थे, तो इसका अर्थ शायद हैश कॉलिशन या खराब रैम (दोनों बेहद दुर्लभ ... मैंने SHA-512 का उपयोग किया था)। इसने रिसीवर को अपूर्ण ब्लॉक या दूषित ब्लॉकों से पुनर्प्राप्त करने की इजाजत दी, जिसमें एक खराब स्थिति-परिदृश्य जुर्माना है, जिसमें 1 खराब ब्लॉक फिर से डाउनलोड किया जा सकता है, जिसे ब्लॉक आकार को ट्यून करके ऑफ़सेट किया जा सकता है।

+0

सराहना की। यदि प्रदर्शन प्रासंगिक नहीं है (या प्रासंगिक बनाम उदा। फ़ाइल-स्थानांतरण-गति नहीं) तो एक ही समय में दो हैंश चलाना निश्चित रूप से एक समाधान है। –

+0

@ मार्टिनबा आप अपने समाधान को ट्विक कर सकते हैं, चंकित हैंश का उपयोग कर सकते हैं लेकिन अगले खंड के इनपुट में आप पिछले खंड के आउटपुट को जोड़ सकते हैं। जब आप हैश को "कॉपी" करना चाहते हैं, तो आपको केवल दूसरी फ़ाइल में उसी ऑफ़सेट पर पुनरारंभ करना होगा और पहले फ़ाइल में पिछले खंड से आउटपुट के साथ बीज करना होगा। असल में एक समान एल्गोरिदम [सीबीसी एन्क्रिप्शन मोड] (http://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Cipher-block_chaining_.28CBC.29) कर रहा है लेकिन इसे XORING के बजाय इनपुट को जोड़ना। –

+1

ओवरहेड खराब नहीं है। मैं एक बफर में एक बार में 32kb/64kb बाइट फ़ाइल पढ़ रहा था। दोनों उदाहरणों ने एक ही बाइट [] बफर को संसाधित किया, इसलिए दो बार हैशिंग के लिए कोई डिस्क I/O जुर्माना नहीं है। आई/ओ वह जगह है जहां से अधिकांश गति जुर्माना आता है। – scottt732

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