2011-10-21 11 views
8

का उपयोग कर फ़ाइल के SHA256 हैश की गणना और मुद्रित करें I फ़ाइल के SHA256 योग की गणना करने के लिए OpenSSL/libcrypto का उपयोग करके एक सी फ़ंक्शन लिखने का प्रयास कर रहा हूं। मैं एडम लैमर के सी ++ उदाहरण here पर अपना कोड लगा रहा हूं।OpenSSL

int main (int argc, char** argv) 
{ 
    char calc_hash[65]; 

    calc_sha256("file.txt", calc_hash); 
} 

int calc_sha256 (char* path, char output[65]) 
{ 
    FILE* file = fopen(path, "rb"); 
    if(!file) return -1; 

    char hash[SHA256_DIGEST_LENGTH]; 
    SHA256_CTX sha256; 
    SHA256_Init(&sha256); 
    const int bufSize = 32768; 
    char* buffer = malloc(bufSize); 
    int bytesRead = 0; 
    if(!buffer) return -1; 
    while((bytesRead = fread(buffer, 1, bufSize, file))) 
    { 
     SHA256_Update(&sha256, buffer, bytesRead); 
    } 
    SHA256_Final(hash, &sha256); 

    sha256_hash_string(hash, output); 
    fclose(file); 
    free(buffer); 
    return 0; 
}  

void sha256_hash_string (char hash[SHA256_DIGEST_LENGTH], char outputBuffer[65]) 
{ 
    int i = 0; 

    for(i = 0; i < SHA256_DIGEST_LENGTH; i++) 
    { 
     sprintf(outputBuffer + (i * 2), "%02x", hash[i]); 
    } 

    outputBuffer[64] = 0; 
} 

समस्या यह .... एक उदाहरण फ़ाइल के लिए नीचे गणना की रकम पर एक नज़र है:: * ढेर का पता चला स्मैश

Known good SHA256: 6da032d0f859191f3ec46a89860694c61e65460d54f2f6760b033fa416b73866 
Calc. by my code: 6dff32ffff59191f3eff6affff06ffff1e65460d54ffff760b033fff16ff3866 

मैं भी हो

यहाँ मेरी कोड है * जब कोड निष्पादित समाप्त हो जाता है।

क्या कोई देखता है कि मैं क्या गलत कर रहा हूं?

धन्यवाद!

+0

मेरे पास प्रोटोटाइप घोषित हैं। – dan6470

+0

क्यों const bufSize 32768 के आकार के साथ तय किया गया है? यह –

उत्तर

12

ऐसा लगता है कि आपके आउटपुट में बहुत सारे '0xff' ब्लॉक हैं, और अच्छी स्ट्रिंग में संबंधित ब्लॉक में उच्च बिट सेट है ... शायद कहीं एक साइन एक्सटेंशन समस्या हो सकती है।

करने का यह:

char hash[SHA256_DIGEST_LENGTH]; 

अहस्ताक्षरित, जैसे:

unsigned char hash[SHA256_DIGEST_LENGTH]; 

मदद करता है? (sha256_hash_string के हस्ताक्षर में विशेष रूप से।)

+0

कम या कम हो सकता है! धन्यवाद! मैं जीसीसी का उपयोग कर उबंटू पर हूं। – dan6470

+1

छोटी-छोटीता के बारे में मेरी टिप्पणी गलत थी, इसलिए मैंने इसे हटा दिया ... एडम के पास इनपुट नकारात्मक होने पर हर बार 8 बाइट मुद्रित होने का सही स्पष्टीकरण था। यह एक अच्छा उदाहरण है, क्यों, "बाइट्स" से निपटने और "स्ट्रिंग वर्ण" नहीं होने पर आपको 'हस्ताक्षरित चार' (या uint8 या इसके रूपों में से एक) का उपयोग करना चाहिए। बेयर 'char' ASCII वर्णों के लिए आरक्षित होना चाहिए। –

11

आप बाहर प्रिंट कर रहे एक पर हस्ताक्षर किएchar एक पूर्णांक के रूप में। यदि बाइट नकारात्मक है, तो इसे signed int (डिफ़ॉल्ट तर्क प्रचार पर कॉल में sprintf) में परिवर्तित कर दिया गया है, और उसके बाद unsigned int (%x स्वरूप विनिर्देशक के माध्यम से) में परिवर्तित हो जाता है और मुद्रित किया जाता है।

तो, बाइट A0 है -96 एक हस्ताक्षरित बाइट है, जो एक signed int रूप -96 में परिवर्तित हो जाता है, जो हेक्स में 0xFFFFFFA0 है, इसलिए यह FFFFFFA0 के रूप में बाहर प्रिंट हो जाती है। हैश के अंत के पास एक हस्ताक्षरित बाइट है क्योंकि

sprintf(..., (unsigned char)hash[i]); 

आप ढेर स्मैश के बारे में चेतावनी हो रही है, तो आप लिख रहे हैं:

मुद्रण से पहले एक unsigned char करने के लिए प्रत्येक बाइट इसे ठीक करने के मामले 8 बाइट एफएफएफएफएफएफबी 7 ऑफ़सेट 58 पर जब आप केवल 2 बाइट लिखना चाहते थे। इसका परिणाम buffer overflow में होता है, जो यहां पाया जाता है क्योंकि संकलक ने वापसी मूल्य से पहले स्टैक में गार्ड क्षेत्र या सुरक्षा कुकी डाली है, और यह पता चला है कि उस गार्ड क्षेत्र को अनजाने में संशोधित किया गया था।

+0

यही वह है! व्याख्या के लिए धन्यवाद !! – dan6470

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