2009-04-26 11 views
34

मैं एक स्ट्रिंग से SHA-1 हैश की गणना करने की कोशिश कर रहा हूं, लेकिन जब मैं php के sha1 फ़ंक्शन का उपयोग कर स्ट्रिंग की गणना करता हूं तो मुझे सी # में कोशिश करने से कुछ अलग मिलता है। मुझे PHP के समान स्ट्रिंग की गणना करने के लिए सी # की आवश्यकता है (क्योंकि php से स्ट्रिंग की गणना किसी तृतीय पक्ष द्वारा की जाती है जिसे मैं संशोधित नहीं कर सकता)। PHP के रूप में एक ही हैश उत्पन्न करने के लिए मैं सी # कैसे प्राप्त कर सकता हूं? धन्यवाद!!!सी # SHA-1 बनाम PHP SHA-1 ... विभिन्न परिणाम?

स्ट्रिंग = [email protected]

सी # कोड (उत्पन्न d32954053ee93985f5c3ca2583145668bb7ade86)

 string encode = secretkey + email; 
     UnicodeEncoding UE = new UnicodeEncoding(); 
     byte[] HashValue, MessageBytes = UE.GetBytes(encode); 
     SHA1Managed SHhash = new SHA1Managed(); 
     string strHex = ""; 

     HashValue = SHhash.ComputeHash(MessageBytes); 
     foreach(byte b in HashValue) { 
      strHex += String.Format("{0:x2}", b); 
     } 

पीएचपी कोड (उत्पन्न a9410edeaf75222d7b576c1b23ca0a9af0dffa98)

sha1(); 
+8

शायद पाठ यूनिकोड के रूप में ASCII एक सिस्टम पर और के रूप में अन्य पर नियंत्रित किया जाता है? – Aziz

+2

आश्चर्यजनक सरल एन्कोडिंग करता है;)। यह तय है, मैंने बस यूनिकोड एन्कोडिंग को ASCIIEncoding में बदल दिया और यह पूरी तरह से काम किया ... बहुत बहुत धन्यवाद! –

उत्तर

35

उपयोग UnicodeEncoding के बजाय ASCIIEncoding। PHP हैश गणना के लिए ASCII वर्णमाला का उपयोग करता है।

+0

धन्यवाद, यह समस्या थी! –

+1

चूंकि किसी ने नीचे अपना उत्तर हटा दिया है, इसलिए यूटीएफ 8 एन्कोडिंग आपके टेस्ट केस में भी काम करेगी लेकिन जब आपके पास यूटीएफ 8 अक्षरों जैसे 艾 हैं तो काम नहीं करेंगे। PHP के साथ काम करते समय उपयोग करने के लिए उचित एन्कोडिंग ASCIIEncoding है। –

+1

चूंकि मुझे इसे खोजने के लिए कुछ समय लगा, चूंकि हैश-फ़ंक्शन में इनपुट को भी ASIDII में परिवर्तित किया जाना चाहिए! और जवाब के लिए धन्यवाद! तो बस महान है! –

1

FWIW, मुझे जावा में एक समान समस्या थी। यह पता चला कि मुझे जावा में एक ही SHA1 हैश बनाने के लिए "यूटीएफ -8" एन्कोडिंग का उपयोग करना था क्योंकि sha1 फ़ंक्शन PHP 5.3.1 (XAMPP Vista पर चल रहा है) में उत्पन्न होता है।

private static String SHA1(final String text) throws NoSuchAlgorithmException, UnsupportedEncodingException { 
     final MessageDigest md = MessageDigest.getInstance("SHA-1"); 
     md.update(text.getBytes("UTF-8")); 
     return new String(org.apache.commons.codec.binary.Hex.encodeHex(md.digest())); 
    } 
2

एक ही समस्या थी। यह कोड मेरे लिए काम करता है:

string encode = secretkey + email; 
SHA1 sha1 = SHA1CryptoServiceProvider.Create(); 
byte[] encodeBytes = Encoding.ASCII.GetBytes(encode); 
byte[] encodeHashedBytes = sha1.ComputeHash(passwordBytes); 
string pencodeHashed = BitConverter. 
ToString(encode HashedBytes).Replace("-", "").ToLowerInvariant(); 
5

मुझे यह समस्या भी थी। निम्नलिखित कोड काम करेगा।

string dataString = "string to hash"; 
SHA1 hash = SHA1CryptoServiceProvider.Create(); 
byte[] plainTextBytes = Encoding.ASCII.GetBytes(dataString); 
byte[] hashBytes = hash.ComputeHash(plainTextBytes); 
string localChecksum = BitConverter.ToString(hashBytes) 
.Replace("-", "").ToLowerInvariant(); 
+0

लगभग यह स्वीकार किया गया था कि मैं ToLowerInvariant को याद कर रहा था। धन्यवाद!!! – AaronLS

-1

निम्नलिखित का प्रयास करें! मुझे लगता है कि यह बहुत अच्छा काम करेगा:

public static string SHA1Encodeb64(string toEncrypt) 
    { 
     //Produce an array of bytes which is the SHA1 hash 
     byte[] sha1Signature = new byte[40]; 

     byte[] sha = System.Text.Encoding.Default.GetBytes(toEncrypt); 
     SHA1 sha1 = SHA1Managed.Create(); 
     sha1Signature = sha1.ComputeHash(sha); 


     /** 
     * The BASE64 encoding standard's 6-bit alphabet, from RFC 1521, 
     * plus the padding character at the end. 
     */ 
     char[] Base64Chars = { 
      'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 
      'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 
      'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 
      'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 
      'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 
      'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 
      'w', 'x', 'y', 'z', '0', '1', '2', '3', 
      '4', '5', '6', '7', '8', '9', '+', '/', 
      '=' 
      }; 
     //Algorithm to encode the SHA1 hash using Base64 
     StringBuilder sb = new StringBuilder(); 
     int len = sha1Signature.Length; 
     int i = 0; 
     int ival; 
     while (len >= 3) 
     { 
      ival = ((int)sha1Signature[i++] + 256) & 0xff; 
      ival <<= 8; 
      ival += ((int)sha1Signature[i++] + 256) & 0xff; 
      ival <<= 8; 
      ival += ((int)sha1Signature[i++] + 256) & 0xff; 
      len -= 3; 
      sb.Append(Base64Chars[(ival >> 18) & 63]); 
      sb.Append(Base64Chars[(ival >> 12) & 63]); 
      sb.Append(Base64Chars[(ival >> 6) & 63]); 
      sb.Append(Base64Chars[ival & 63]); 
     } 
     switch (len) 
     { 
      case 0: // No pads needed. 
       break; 
      case 1: // Two more output bytes and two pads. 
       ival = ((int)sha1Signature[i++] + 256) & 0xff; 
       ival <<= 16; 
       sb.Append(Base64Chars[(ival >> 18) & 63]); 
       sb.Append(Base64Chars[(ival >> 12) & 63]); 
       sb.Append(Base64Chars[64]); 
       sb.Append(Base64Chars[64]); 
       break; 
      case 2: // Three more output bytes and one pad. 
       ival = ((int)sha1Signature[i++] + 256) & 0xff; 
       ival <<= 8; 
       ival += ((int)sha1Signature[i] + 256) & 0xff; 
       ival <<= 8; 
       sb.Append(Base64Chars[(ival >> 18) & 63]); 
       sb.Append(Base64Chars[(ival >> 12) & 63]); 
       sb.Append(Base64Chars[(ival >> 6) & 63]); 
       sb.Append(Base64Chars[64]); 
       break; 
     } 
     //Encode the signature using Base64 
     string base64Sha1Signature = sb.ToString(); 
     return base64Sha1Signature; 
    } 
+1

'System.Text.Encoding.Default' का उपयोग कर स्ट्रिंग्स और क्रिप्टोग्राफी से निपटने पर ** ** बहुत ** बुरा विचार है। विभिन्न प्लेटफ़ॉर्म अलग-अलग डिफ़ॉल्ट (यूटीएफ 8, एएससीआईआईआई, यूनिकोड) का उपयोग करते हैं और 'डिफ़ॉल्ट' का उपयोग करके इसे और भी जटिल बनाते हैं (क्योंकि यह सिस्टम, कॉन्फ़िगरेशन और संस्करणों के बीच बदल सकता है)। – poupou

+0

.NET में एक बेस 64 एन्कोडर है। इसके अलावा मैं 'बाइट [] sha1Signature = नया बाइट [40];', और फिर 'sha1Signature = sha1.ComputeHash (sha); '। आपको 'नया बाइट [40] 'की आवश्यकता नहीं है। – quantum

9

.NET में इस विधि php में SHA1 के बराबर है:

string sha1Hash(string password) 
{ 
    return string.Join("", SHA1CryptoServiceProvider.Create().ComputeHash(Encoding.UTF8.GetBytes(password)).Select(x => x.ToString("x2"))); 
} 
+0

बस विनम्र: क्यों 'string.Join'? – Spontifixus

+1

चयन (...) विधि तारों की एक सरणी आउटपुट करती है, प्रत्येक कंप्यूटैशैश() विधि द्वारा लौटाए गए बाइट्स से एक बाइट का प्रतिनिधित्व करता है, इन तारों को एक साथ रखा जाना चाहिए, एक के बाद एक। जॉइन विधि में यह प्रोटोटाइप है: स्ट्रिंग.जॉइन (स्ट्रिंग सेपरेटर, पैराम्स स्ट्रिंग [] मान), देखें (http://msdn.microsoft.com/en-us/library/57a79xd0.aspx)। – OmarElsherif

+0

आह ...दाईं ओर स्क्रॉल नहीं किया, इस प्रकार चयन को नहीं देखा। उस सवाल को भूल जाओ। ;) – Spontifixus

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