2016-12-12 47 views
3

我使用openSSL庫在C中編寫了一個最簡單的例子sha256sha1在C中使用openssl庫的例子

// compile with: gcc -o sha256 sha256.c -lcrypto 

#include <openssl/sha.h> 
#include <stdio.h> 
int main(int argc, char **argv) 
{ 
    unsigned char buffer[BUFSIZ]; 
    FILE *f; 
    SHA256_CTX ctx; 
    size_t len; 
    if (argc < 2) { 
     fprintf(stderr, "usage: %s <file>\n", argv[0]); 
     return 1; 
    } 

    f = fopen(argv[1], "r"); 
    if (!f) { 
     fprintf(stderr, "couldn't open %s\n", argv[1]); 
     return 1; 
    } 

    SHA256_Init(&ctx); 

    do { 
     len = fread(buffer, 1, BUFSIZ, f); 
     SHA256_Update(&ctx, buffer, len); 
    } while (len == BUFSIZ); 

    SHA256_Final(buffer, &ctx); 

    fclose(f); 

    for (len = 0; len < SHA256_DIGEST_LENGTH; ++len) 
     printf("%02x", buffer[len]); 
    putchar('\n'); 
    return 0; 
} 

我需要相同的sha1,但我找不到類似的實際工程的簡單例子。在上面的代碼中用SHA1代替SHA256事件的幼稚方法不起作用(顯然)。

如何修改SHA1的程序?

UPDATE

由@dbush建議,我用他的EVP代碼,並將其集成到我的程序。我的計劃現在看起來是這樣的:

#include <stdio.h> 
#include <openssl/sha.h> 
#include <openssl/evp.h> 
#include <openssl/err.h> 

int main(int argc, char **argv) 
{ 

FILE *f; 
size_t len; 
unsigned char buffer[BUFSIZ]; 

if (argc < 2) { 
    fprintf(stderr, "usage: %s <file>\n", argv[0]); 
    return 1; 
} 

f = fopen(argv[1], "r"); 

if (!f) { 
    fprintf(stderr, "couldn't open %s\n", argv[1]); 
    return 1; 
} 


EVP_MD_CTX hashctx; 
//EVP_MD *hashptr = EVP_get_digestbyname("SHA256"); 
EVP_MD *hashptr = EVP_get_digestbyname("SHA1"); 

EVP_MD_CTX_init(&hashctx); 
EVP_DigestInit_ex(&hashctx, hashptr, NULL)); 

do { 
    len = fread(buffer, 1, BUFSIZ, f); 
    EVP_DigestUpdate(&hashctx, buffer, len); 
} while (len == BUFSIZ); 

EVP_DigestFinal_ex(&hashctx, buffer, &len); 
EVP_MD_CTX_cleanup(&hashctx); 

fclose(f); 

int i; 
for (i = 0; i < len; ++i) 
    printf("%02x", buffer[i]); 

    return 0; 
} 

當我把它用gcc -o evp evp.c -lcrypto編譯,我得到幾個錯誤,如:

evp.c: In function ‘main’: 
evp.c:29:19: warning: initialization discards ‘const’ qualifier from pointer target type [enabled by default] 
evp.c:32:43: error: expected ‘;’ before ‘)’ token 
evp.c:32:43: error: expected statement before ‘)’ token 
evp.c:39:1: warning: passing argument 3 of ‘EVP_DigestFinal_ex’ from incompatible pointer type [enabled by default] 
In file included from evp.c:4:0: 
/usr/include/openssl/evp.h:574:5: note: expected ‘unsigned int *’ but argument is of type ‘size_t *’ 
+0

調用兩個OpenSSL的初始化函數如果您所遇到的*「警告:初始化丟棄‘const’限定符......」 *警告,那麼我相信你使用的是真正的老版本的OpenSSL。也許OS X上的OpnSSL 0.9.8?您可能需要考慮更新庫。 – jww

+0

@jww - 我在Debian上使用'libssl-dev'版本'1.0.1t-1 + deb7u1'。 –

回答

3

而不是使用SHA1或SHA256特定的功能,使用EVP_Digest*與任何散列一起工作的函數族。

... 

// makes all algorithms available to the EVP* routines 
OpenSSL_add_all_algorithms(); 
// load the error strings for ERR_error_string 
ERR_load_crypto_strings(); 

EVP_MD_CTX hashctx; 
//const EVP_MD *hashptr = EVP_get_digestbyname("SHA256"); 
const EVP_MD *hashptr = EVP_get_digestbyname("SHA1"); 

EVP_MD_CTX_init(&hashctx); 
EVP_DigestInit_ex(&hashctx, hashptr, NULL); 

do { 
    len = fread(buffer, 1, BUFSIZ, f); 
    EVP_DigestUpdate(&hashctx, buffer, len); 
} while (len == BUFSIZ); 

unsigned int outlen; 
EVP_DigestFinal_ex(&hashctx, buffer, &outlen); 
EVP_MD_CTX_cleanup(&hashctx); 

fclose(f); 

int i; 
for (i = 0; i < outlen; ++i) 
    printf("%02x", buffer[i]); 

爲了簡潔,我省略了錯誤檢查。要檢查錯誤,請執行以下操作:

if (function_to_check() == 0) { 
    char errstr[1000]; 
    ERR_error_string(ERR_get_error(), errstr); 
    printf("error: %s\n", errstr; 
} 

編輯:

有在上面的代碼中的一些錯誤已經得到糾正:

  • hashptr被宣佈EVP_MD *,現在是const EVP_MD *
  • EVP_DigestInit_ex呼叫有一個額外的括號在端
  • EVP_DigestFinal_ex第三個參數是專門給定的unsigned int *代替size_t *,它可能不一定是相同的。
  • 添加在頂部
+0

謝謝。您能否添加其餘的缺失代碼,以便我可以完全複製它?此刻,當將代碼粘貼到我的程序中(替換相關部分)時,我會遇到一些錯誤。另外,我相信你在這裏有一個錯字:'for(i = 0; len

+0

@MininVegter你需要'#include '和'#include '。除此之外,它應該工作。如果沒有,請使用相關代碼更新您的問題(或發佈新問題)。 – dbush

+0

@MartinVegter我最初發布的內容中有一些錯誤。我編輯了我的示例代碼並確認它正確運行。 – dbush