2016-08-18 18 views
7

मैं एक बिगइंटर/बिग्नम हैश करने की कोशिश कर रहा हूं और मुझे एंड्रॉइड/आईओएस में अलग-अलग परिणाम मिल रहे हैं। मुझे एक ही हैश परिणाम प्राप्त करने की आवश्यकता है ताकि दोनों ऐप्स एसआरपी प्रोटोकॉल के अनुसार काम कर सकें। नज़दीकी निरीक्षण पर यह सकारात्मक संख्याओं के लिए ठीक काम कर रहा है लेकिन नकारात्मक संख्याओं के लिए काम नहीं कर रहा है (7 से अधिक पहले निबल)। सुनिश्चित नहीं है कि कौन सा सही है और दूसरे के साथ मिलान करने के लिए कौन सा समायोजित किया जाना है।SHA256 हैश परिणाम बड़ी संख्या के लिए एंड्रॉइड और आईओएस में भिन्न हैं

एंड्रॉयड:

void hashBigInteger(String s) { 
    try { 
     BigInteger a = new BigInteger(s, 16); 
     MessageDigest sha = MessageDigest.getInstance("SHA-256"); 
     byte[] b = a.toByteArray(); 
     sha.update(b, 0, b.length); 
     byte[] digest = sha.digest(); 
     BigInteger d = new BigInteger(digest); 
     Log.d("HASH", "H = " + d.toString(16)); 
    } catch (NoSuchAlgorithmException e) { 
     throw new UnsupportedOperationException(e); 
    } 
} 

iOS:

void hashBigNum(unsigned char *c) { 
    BIGNUM *n = BN_new(); 
    BN_hex2bn(&n, c); 
    unsigned char buff[ SHA256_DIGEST_LENGTH ]; 
    int    len = BN_num_bytes(n); 
    unsigned char * bin = (unsigned char *) malloc(len); 
    BN_bn2bin(n, bin); 
    hash(SRP_SHA256, bin, len, buff); 
    fprintf(stderr, "H: "); 
    for (int z = 0; z < SHA256_DIGEST_LENGTH; z++) 
     fprintf(stderr, "%2x", buff[z]); 
    fprintf(stderr, "\n"); 
    free(bin); 
} 

परिणाम:

Source String = "6F" 
Android Hash = 65c74c15a686187bb6bbf9958f494fc6b80068034a659a9ad44991b08c58f2d2 
iOS  Hash = 65c74c15a686187bb6bbf9958f494fc6b80068034a659a9ad44991b08c58f2d2 

Source String = "FF" 
Android Hash = 06eb7d6a69ee19e5fbdf749018d3d2abfa04bcbd1365db312eb86dc7169389b8 
iOS  Hash = a8100ae6aa1940d0b663bb31cd466142ebbdbd5187131b92d93818987832eb89 
+0

साथ भी BigInteger d = new BigInteger(digest); बदलने के लिए, यह Android और iOS के बीच हैश मैच के लिए पर्याप्त नहीं है। हैश को यह जानने की जरूरत है कि स्पेक कहता है कि उन्हें क्या होना चाहिए। मैं किसी और के कार्यान्वयन का उपयोग करने का सुझाव देता हूं और देख रहा हूं कि उन्हें क्या हैश मिलते हैं। –

+0

@brianbeuning, हमने इस बिट को छोड़कर सभी प्रोटोकॉल को लागू किया है। एक बार जब मैंने अग्रणी 0s समस्या के लिए जावा कोड तय किया, तो यह ठीक क्रॉस प्लेटफार्म काम कर रहा है। – Harish

+0

उदाहरण के लिए, ओपनएसएसएल एसआरपी का समर्थन करता है। यदि आप एसआरपी हैश की गणना करते हैं तो ओपनएसएसएल एसआरपी हैश की गणना करने के तरीके से मेल नहीं खाता है, आपका कोड OpenSSL से बात करने में सक्षम नहीं होगा। –

उत्तर

3

समस्या जावा कोड में है। new BigInteger(s, 16).toByteArray()अग्रणी शून्यों के लिए सुरक्षित नहीं है। देखें पोस्टर टिप्पणी Convert a string representation of a hex dump to a byte array using Java?

पर Android के साथ एफएफ की बिट प्रतिनिधित्व 0000000011111111 है, जबकि आईओएस में 11111111 है। अग्रणी शून्य कारण है क्योंकि SHA256 हैशिंग अलग है।

उसी बाइट सरणी (शून्य के बिना) प्राप्त करने के लिए लिंक किए गए पोस्ट की एक विधि का उपयोग करके हेक्स को बाइट कनवर्टर में बदलें। उदाहरण

public static byte[] hexStringToByteArray(String s) { 
    int len = s.length(); 
    byte[] data = new byte[len/2]; 
    for (int i = 0; i < len; i += 2) { 
     data[i/2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) 
          + Character.digit(s.charAt(i+1), 16)); 
    } 
    return data; 
} 

void hashBigInteger(String s){ 
    try{ 
     MessageDigest sha = MessageDigest.getInstance("SHA-256"); 
     byte b[] = hexStringToByteArray(s); 
     sha.update(b,0,b.length); 
     byte digest[] = sha.digest(); 
     BigInteger d = new BigInteger(1,digest); 

     System.out.println("H "+d.toString(16)); 
    }catch (NoSuchAlgorithmException e){ 
     throw new UnsupportedOperationException(e); 
    } 
} 

उचित हेक्स मुद्रण करने के लिए के लिए, आप SRP लागू करना चाहते हैं

BigInteger d = new BigInteger(1,digest); 
+2

दूसरे शब्दों में, यह दो के पूरक के बारे में आपके प्रश्न में मैंने जो किया उसके विपरीत है। BigInteger को बाइट सरणी में कनवर्ट करें और * हटाएं * अग्रणी शून्य बाइट, और संशोधित सरणी के साथ एक नया BigInteger बनाएं। जावा -1 के रूप में व्याख्या करेगा, लेकिन इसे आजमाएं। –

0

एक तरह से तार करने के लिए अपने बड़े संख्या बदलती है और उनमें से हैश प्राप्त करने के लिए है।

+0

बिगइंटर/बिगनम स्ट्रिंग्स से ही बनाए जाते हैं, इसलिए यदि हम उन्हें स्ट्रिंग्स में वापस परिवर्तित करते हैं तो इससे कोई फर्क पड़ता है? आईओएस में भी हैश ओपनएसएसएल पुस्तकालयों का उपयोग करता है जो निम्न स्तर सी एपीआई हैं, यह सुनिश्चित नहीं है कि हम हैश एपीआई के लिए स्ट्रिंग का उपयोग कैसे कर सकते हैं। – Harish

+1

बिगइंटर और बिग्नम में अलग-अलग कार्यान्वयन हो सकते हैं, इसलिए बाइट एरे में उनके रूपांतरण अलग-अलग परिणाम उत्पन्न कर सकते हैं। –

+0

लेकिन एसआरपी प्रोटोकॉल (https://en.wikipedia.org/wiki/Secure_Remote_Password_protocol) गणनाओं को BigInteger/BigNum की आवश्यकता है और इसलिए मैं एक ही हैश परिणाम प्राप्त करना चाहता हूं। यह + संख्याओं के लिए काम कर रहा है, इसलिए यह जानना है कि एक मंच पर हस्ताक्षर किए गए हैं -व संख्याओं के रूप में हस्ताक्षर किए गए हैं और अन्य व्यवहार + ve – Harish

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