2011-10-21 147 views
8

我想使用OpenSSL/libcrypto來編寫C函數來計算文件的SHA256總和。我將我的代碼基於Adam Lamer的C++示例here使用OpenSSL計算和打印文件的SHA256哈希

這裏是我的代碼:

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 int bufSize的大小是32768?它可能是或多或少的 –

回答

12

看起來你的輸出中有很多'0xff'塊,而好字符串中的對應塊有高位設置...也許是某處的符號擴展問題。

是否使:

char hash[SHA256_DIGEST_LENGTH]; 

符號,就像:

unsigned char hash[SHA256_DIGEST_LENGTH]; 

幫助? (特別是在簽名sha256_hash_string。)

+0

修復它!謝謝!我在Ubuntu上使用gcc。 – dan6470

+1

我對little-endianess的評論是錯誤的,所以我把它刪除了...... Adam每次輸入都是負數時,都有正確的解釋8個字節。這是一個很好的例子,爲什麼在處理「字節」而不是「字符串」時,應該使用'unsigned char'(或uint8或其變體之一)。裸露的'char'應該保留給ASCII字符。 –

11

您正在打印一個簽署char作爲一個整數。如果該字節爲負值,則將其轉換爲signed int(在調用sprintf默認參數促銷),然後將其轉換爲unsigned int(通過%x格式說明符)並打印出來。

因此,字節A0是-96作爲有符號字節,它被轉換爲-96作爲signed int,它是十六進制的0xFFFFFFA0,因此它被打印爲FFFFFFA0。

在打印之前解決這個問題,情況下,每個字節的unsigned char

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

你得到關於堆棧溢出的警告,因爲有附近的哈希結束一個符號字節,所以你寫當您打算只寫入2個字節時,偏移量爲58的8個字節FFFFFFB7。這導致了buffer overflow,這恰好在此處被檢測到,因爲編譯器可能在返回值之前在堆棧中插入了警戒區域或安全cookie,並且它檢測到該警戒區域被無意中修改。

+0

就是這樣!感謝您的解釋! – dan6470