2016-12-12 3 views
3

Ich habe ein einfaches mögliches Beispiel von sha256 in C geschrieben, mit der OpenSSL-Bibliothek.sha1 Beispiel in C mit openssl-Bibliothek

// 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; 
} 

muss ich das gleiche für sha1, aber ich konnte nicht ähnlich einfaches Beispiel finden, die tatsächlich funktioniert. Der naive Ansatz des Ersetzens von Vorkommen SHA256 in dem obigen Code mit SHA1 funktioniert (offensichtlich) nicht.

Wie kann ich mein Programm für SHA1 ändern?

UPDATE

wie @dbush vorgeschlagen, ich habe seine EVP Code verwendet, und integriert sie in mein Programm. Mein Programm sieht nun wie folgt aus:

#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; 
} 

Wenn ich kompilieren gcc -o evp evp.c -lcrypto verwenden, erhalte ich einige Fehler, wie zum Beispiel:

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

Wenn Sie die stoßen * „Warnung: Initialisierung entledigt‚const‘Qualifier ...“ * Warnungen, dann glaube ich Ihnen eine wirklich alte Version verwenden von OpenSSL. Vielleicht OpnSSL 0.9.8 auf OS X? Möglicherweise möchten Sie die Aktualisierung der Bibliothek in Betracht ziehen. – jww

+0

@jww - Ich benutze 'libssl-dev' Version' 1.0.1t-1 + deb7u1' auf Debian. –

Antwort

3

Anstatt mit dem SHA1 oder SHA256 spezifischen Funktionen, verwenden Sie die EVP_Digest* Familie von Funktionen, die mit jedem Hash funktionieren.

... 

// 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]); 

Ich habe die Fehlerüberprüfung für die Kürze weggelassen. Um Fehler zu überprüfen, gehen Sie wie folgt:

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

EDIT:

Es gab einige Fehler in dem obigen Code, wurden korrigiert:

  • hashptr wurde EVP_MD * erklärt, ist jetzt const EVP_MD *.
  • Der Aufruf von EVP_DigestInit_ex hatte eine zusätzliche Klammer am Ende
  • Der dritte Parameter zu EVP_DigestFinal_ex spezifisch ein unsigned int * anstelle ein size_t * gegeben wird, was nicht unbedingt das gleiche sein kann.
  • hinzugefügt ruft zwei OpenSSL Initialisierungsfunktionen am oberen
+0

danke. Könnten Sie bitte den Rest des fehlenden Codes hinzufügen, damit ich ihn genau kopieren kann? Im Moment, wenn Sie Ihren Code in mein Programm einfügen (ersetze relevante Teile), bekomme ich ein paar Fehler. Außerdem glaube ich, dass Sie hier einen Tippfehler haben: 'für (i = 0; len

+0

@MartinVegter Sie müssen <#include 'und' # include '. Ansonsten sollte es funktionieren. Wenn nicht, aktualisieren Sie Ihre Frage (oder schreiben Sie eine neue) mit dem entsprechenden Code. – dbush

+0

@MartinVegter Es gab ein paar Fehler in dem, was ich ursprünglich gepostet habe. Ich habe meinen Beispielcode bearbeitet und bestätigt, dass er korrekt ausgeführt wird. – dbush