2013-11-22 17 views
6

मैं एक विस्तार विधि लिख रहा हूं जो बॉयलरप्लेट के एक टन को हटाकर हैश के निर्माण को सरल बनाता है, मेरी समस्या यह है कि जब भी मैं कोड के माध्यम से कदम उठाता हूं, तो मैं देख सकता हूं कि यह हमेशाSHA256Managed चुनता है, भले ही नहीं मैं फोन SHA256.Create(), SHA256Cng.Create(), SHA256Managed.Create() या SHA256CryptoServiceProvider.Create()SHA256 के सभी प्रकार SHA256 प्रबंधित क्यों होते हैं?

जब मैं एम डी 5 की तरह एक अलग हैशिंग एल्गोरिथ्म लेने यह वही कहानी है, लेकिन MD5 के मामले में यह हमेशा की पसंद वर्ग की परवाह किए बिना MD5CryptoServiceProvider कि मैं वास्तव में उपयोग करें ...

क्यों मैं क्या वह है?

यहाँ मेरी कोड है:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Security.Cryptography; 
using System.Text; 
using System.Threading.Tasks; 

namespace Utility.Methods 
{ 
    public enum HashType { MD5, SHA512, SHA256, SHA384, SHA1 } 
    public enum HashSubType {Normal, Cng, Managed, CryptoServiceProvider} 

    public static class TextHasher 
    { 
     public static string Hash(this string input, HashType hash, HashSubType subType = HashSubType.Normal) 
     { 
      Func<HashAlgorithm, string> hashFunction = alg => HashingHelper(input, alg); 

      switch (subType) 
      { 
       case HashSubType.Normal: 
        return hashFunction(NormalHashes(hash)); 
       case HashSubType.Cng: 
        return hashFunction(CngHashes(hash)); 
       case HashSubType.Managed: 
        return hashFunction(ManagedHashes(hash)); 
       case HashSubType.CryptoServiceProvider: 
        return hashFunction(CSPHashes(hash)); 
       default: return "error"; // unreachable 
      } 
     } 

     private static string HashingHelper(string text, HashAlgorithm algorithm) 
     { 
      Func<string, byte[]> getHash = input => algorithm.ComputeHash(Encoding.UTF8.GetBytes(input)); 

      var sb = new StringBuilder(); 
      Array.ForEach(getHash(text), b => sb.Append(b.ToString("X"))); 

      return sb.ToString(); 
     } 

     private static HashAlgorithm NormalHashes(HashType hash) 
     { 
      switch (hash) 
      { 
       case HashType.MD5: 
        return MD5.Create(); 
       case HashType.SHA1: 
        return SHA1.Create(); 
       case HashType.SHA256: 
        return SHA256.Create(); 
       case HashType.SHA384: 
        return SHA384.Create(); 
       case HashType.SHA512: 
        return SHA512.Create(); 
       default: return null; // unreachable 
      } 
     } 

     private static HashAlgorithm CngHashes(HashType hash) 
     { 
      switch (hash) 
      { 
       case HashType.MD5: 
        return MD5Cng.Create(); 
       case HashType.SHA1: 
        return SHA1Cng.Create(); 
       case HashType.SHA256: 
        return SHA256Cng.Create(); 
       case HashType.SHA384: 
        return SHA384Cng.Create(); 
       case HashType.SHA512: 
        return SHA512Cng.Create(); 
       default: return null; // unreachable 
      } 
     } 

     private static HashAlgorithm ManagedHashes(HashType hash) 
     { 
      switch (hash) 
      { 
       case HashType.SHA1: 
        return SHA1Managed.Create(); 
       case HashType.SHA256: 
        return SHA256Managed.Create(); 
       case HashType.SHA384: 
        return SHA384Managed.Create(); 
       case HashType.SHA512: 
        return SHA512Managed.Create(); 
       default: return null; // unreachable 
      } 
     } 

     private static HashAlgorithm CSPHashes(HashType hash) 
     { 
      switch (hash) 
      { 
       case HashType.MD5: 
        return MD5CryptoServiceProvider.Create(); 
       case HashType.SHA1: 
        return SHA1CryptoServiceProvider.Create(); 
       case HashType.SHA256: 
        return SHA256CryptoServiceProvider.Create(); 
       case HashType.SHA384: 
        return SHA384CryptoServiceProvider.Create(); 
       case HashType.SHA512: 
        return SHA512CryptoServiceProvider.Create(); 
       default: return null; // unreachable 
      } 
     } 
    } 
} 

तो, किसी भी मदद?

+0

यह विशेष रूप से आश्चर्य की बात के बाद से 'Create' स्थिर पर परिभाषित किया गया है नहीं है (लेकिन मैं सोचा था यह चेतावनी पैदा किया जाना चाहिए)' SHA256' वर्ग, और अन्य वर्ग उस से प्राप्त होते हैं, और इसलिए आप प्रत्येक मामले में एक ही विधि को बुला रहे हैं। गैर-सार वर्गों में सार्वजनिक निर्माता हैं। –

+0

तो कक्षा के अन्य संस्करण होने का क्या मतलब है यदि निर्माण विधि यह नहीं बदलती है कि यह क्या कर रहा है? –

+0

क्योंकि उन वर्गों के उदाहरण अलग-अलग चीजें करते हैं। वे आपके उपयोग के मामले के लिए प्रासंगिक नहीं हैं। – Mark

उत्तर

10

ऐसा इसलिए है क्योंकि आप हमेशा एक ही स्थिर विधि, SHA256.Create पर कॉल कर रहे हैं। SHA256 एक अमूर्त वर्ग है और इसके वंशज एक वैकल्पिक विधि प्रदान करते हैं। वास्तव में, रिशेर्पर आपको एक चेतावनी देगा कि आप व्युत्पन्न प्रकार से स्थिर सदस्य तक पहुंच रहे हैं।

वास्तव में, SHA256 को कॉल करना। क्रेते HashAlgorithm.Create पर कॉल करने जैसा ही है। दोनों वर्ग आंतरिक रूप से एक ही कार्यान्वयन को कॉल करते हैं और परिणाम को विभिन्न प्रकारों में डाल देते हैं।

डिफ़ॉल्ट कार्यान्वयन कि machine.config में निर्दिष्ट किया जाता है और अपने app.config में ओवरराइड किया जा सकता

आप एक विशिष्ट प्रदाता का उपयोग करना चाहते हैं, SHA256.Create(string) प्रदाता का नाम गुजर का उपयोग पैदा करेगा SHA256.Create विधि आप उपयोग करना चाहते हैं।

उदाहरण हैं:

SHA256.Create("System.Security.Cryptography.SHA256Cng"); 
HashAlgorithm.Create("System.Security.Cryptography.SHA256Cng"); 
SHA256.Create("System.Security.Cryptography.SHA256CryptoServiceProvider"); 

संपादित

HashAlgorithm.Create के प्रलेखन वैध एल्गोरिथ्म नामों की सूची निर्दिष्ट करता है। एमएसडीएन आलेख Mapping Algorithm Names to Cryptography Classes वर्णन करता है कि आप अन्य प्रदाताओं (अपनी खुद की, तृतीय-पक्ष, हार्डवेयर-त्वरित या जो कुछ भी) में एल्गोरिदम नामों को कैसे मैप कर सकते हैं और डिफ़ॉल्ट एल्गोरिदम के बजाय उनका उपयोग कर सकते हैं।

संपादित 2

यह भी संभव है प्रोग्राम के रूप में मैपिंग बदलने के लिए। तो, SHA512CryptoServiceProvider करने के लिए "डॉग" मैप करने के लिए, तो आप सिर्फ लिखने के लिए की जरूरत है:

CryptoConfig.AddAlgorithm(
      typeof(System.Security.Cryptography.SHA512CryptoServiceProvider), 
      "Dog"); 
var t4 = HashAlgorithm.Create("Dog"); 
+0

लेकिन मैं हर बार sha256.create का उपयोग नहीं करता ... मैं दूसरों के लिए sha256Managed.create और sha256Cng.create का उपयोग करता हूं, और यह अभी भी मुझे एक ही परिणाम देता है ... –

+1

@ElectricCoffee - कोई 'sha256 प्रबंधित नहीं है। 'विधि - लेकिन 'शा2525' से' sha256 प्रबंधित '* विरासत * और इसलिए कॉल संकलित किया जा सकता है। –

+0

तो बिंदु क्या है? –

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