2010-02-14 17 views
49

Ich suche einen Hash mit sha256 mit openssl und C++ zu erstellen. Ich weiß, dass es einen ähnlichen Beitrag bei Generate SHA hash in C++ using OpenSSL library gibt, aber ich suche speziell sha256 zu erstellen.Erzeuge sha256 mit OpenSSL und C++

UPDATE:

scheint ein Problem mit den Pfaden enthalten zu sein. Es kann keine OpenSSL Funktionen finden, obwohl ich

#include "openssl/sha.h" 

enthalten und ich eingeschlossen die Pfade in meinem Build

-I/opt/ssl/include/ -L/opt/ssl/lib/ -lcrypto 
+0

Auch als Bonus wäre es nett, wenn es den Hash in binär ausgeben würde :) –

+1

Ich postete eine neue Antwort, die erklärt, was Sie wollen. Sie können diese Frage als Duplikat schließen, wenn diese Antwort hilft. – AndiDog

+0

@AndiDog - Alles scheint richtig zu funktionieren, außer der Compiler kann die Funktionen nicht finden. Es konnte nicht einmal einen Verweis auf SHA1 finden. Auch keine der SHA256-Funktionen wie 'SHA256_Final 'konnte gefunden werden. Nicht sicher, was ich falsch mache, ich habe #include "openssl/sha.h" eingeschlossen und ich habe das Include und die Bibliothek während der Kompilierung eingefügt -I/opt/ssl/include/-L/opt/ssl/lib/-lcrypto –

Antwort

58

Hier ist, wie ich es tat:

void sha256(char *string, char outputBuffer[65]) 
{ 
    unsigned char hash[SHA256_DIGEST_LENGTH]; 
    SHA256_CTX sha256; 
    SHA256_Init(&sha256); 
    SHA256_Update(&sha256, string, strlen(string)); 
    SHA256_Final(hash, &sha256); 
    int i = 0; 
    for(i = 0; i < SHA256_DIGEST_LENGTH; i++) 
    { 
     sprintf(outputBuffer + (i * 2), "%02x", hash[i]); 
    } 
    outputBuffer[64] = 0; 
} 

int sha256_file(char *path, char outputBuffer[65]) 
{ 
    FILE *file = fopen(path, "rb"); 
    if(!file) return -534; 

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

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

es ist c Ursprungserzeugnisse wie folgt aus:

static unsigned char buffer[65]; 
sha256("string", buffer); 
printf("%s\n", buffer); 
+1

verwendet Hallo, für alle, die das großartige QT verwenden :) - Sie können dies auch verwenden , fügen Sie einfach zu Ihrer Projektdatei 'LIBS + = - lcrypto' hinzu und dann können Sie den Code einfach in eine Klasse konvertieren und alles wird gut funktionieren;) – TCB13

+3

-1:" SHA1_Init(), SHA1_Update() und SHA1_Final() geben 1 zurück für Erfolg, 0 sonst. ", http://www.openssl.org/docs/crypto/sha.htm. – jww

+0

@noloader Irrelevant, da diese Funktionen hier nicht verwendet werden. –

1

Ich denke, dass Sie nur SHA1-Funktion mit SHA256-Funktion mit tatk Code ersetzen von Link in Ihrem Beitrag

2

Eine "C++" ish Version

#include <iostream> 
#include <sstream> 

#include "openssl/sha.h" 

using namespace std; 

string to_hex(unsigned char s) { 
    stringstream ss; 
    ss << hex << (int) s; 
    return ss.str(); 
} 

string sha256(string line) {  
    unsigned char hash[SHA256_DIGEST_LENGTH]; 
    SHA256_CTX sha256; 
    SHA256_Init(&sha256); 
    SHA256_Update(&sha256, line.c_str(), line.length()); 
    SHA256_Final(hash, &sha256); 

    string output = "";  
    for(int i = 0; i < SHA256_DIGEST_LENGTH; i++) { 
     output += to_hex(hash[i]); 
    } 
    return output; 
} 

int main() { 
    cout << sha256("hello, world") << endl; 

    return 0; 
} 
+1

-1: "SHA1_Init(), SHA1_Update() und SHA1_Final() zurückgegeben 1 für Erfolg, 0 sonst. ", Openssl.org/docs/crypto/sha.htm. – jww

+3

wollte den Code mit C-Style-Rückgabewertprüfungen nicht verdecken. DIY, wenn Sie sich interessieren – Max

+9

"DIY, wenn Sie sich interessieren" - entschuldigen Sie die Unannehmlichkeit. Leute werden es blind kopieren/einfügen. Das Ignorieren von Rückgabewerten ist eine gefährliche Vorgehensweise und sollte nicht demonstriert werden (insbesondere bei Code mit hoher Integrität). – jww

30

std basierend

#include <iostream> 
#include <iomanip> 
#include <sstream> 
#include <string> 

using namespace std; 

#include <openssl/sha.h> 
string sha256(const string str) 
{ 
    unsigned char hash[SHA256_DIGEST_LENGTH]; 
    SHA256_CTX sha256; 
    SHA256_Init(&sha256); 
    SHA256_Update(&sha256, str.c_str(), str.size()); 
    SHA256_Final(hash, &sha256); 
    stringstream ss; 
    for(int i = 0; i < SHA256_DIGEST_LENGTH; i++) 
    { 
     ss << hex << setw(2) << setfill('0') << (int)hash[i]; 
    } 
    return ss.str(); 
} 

int main() { 
    cout << sha256("1234567890_1") << endl; 
    cout << sha256("1234567890_2") << endl; 
    cout << sha256("1234567890_3") << endl; 
    cout << sha256("1234567890_4") << endl; 
    return 0; 
} 
+3

Habe das nicht getestet, aber das sieht definitiv sauberer aus als alle anderen "C++" Versionen. –

+4

Dieser Code kompiliert und produziert die erwartete Ausgabe. Auf Ubuntu können Sie Folgendes verwenden: sudo apt-get install libssl-dev && g ++ -lcrypto main.cc, um es zu kompilieren. – Homer6

+1

Diese Lösung ist eigentlich besser als die akzeptierte, da ostringstream viel, viel sicherer ist als mit Arrays und 'sprintf' zu verwirren. – omni

5

Mit OpenSSL EVP interface ist (das folgende ist für OpenSSL 1.1):

#include <iomanip> 
#include <iostream> 
#include <sstream> 
#include <string> 
#include <openssl/evp.h> 

bool computeHash(const std::string& unhashed, std::string& hashed) 
{ 
    bool success = false; 

    EVP_MD_CTX* context = EVP_MD_CTX_new(); 

    if(context != NULL) 
    { 
     if(EVP_DigestInit_ex(context, EVP_sha256(), NULL)) 
     { 
      if(EVP_DigestUpdate(context, unhashed.c_str(), unhashed.length())) 
      { 
       unsigned char hash[EVP_MAX_MD_SIZE]; 
       unsigned int lengthOfHash = 0; 

       if(EVP_DigestFinal_ex(context, hash, &lengthOfHash)) 
       { 
        std::stringstream ss; 
        for(unsigned int i = 0; i < lengthOfHash; ++i) 
        { 
         ss << std::hex << std::setw(2) << std::setfill('0') << (int)hash[i]; 
        } 

        hashed = ss.str(); 
        success = true; 
       } 
      } 
     } 

     EVP_MD_CTX_free(context); 
    } 

    return success; 
} 

int main(int, char**) 
{ 
    std::string pw1 = "password1", pw1hashed; 
    std::string pw2 = "password2", pw2hashed; 
    std::string pw3 = "password3", pw3hashed; 
    std::string pw4 = "password4", pw4hashed; 

    hashPassword(pw1, pw1hashed); 
    hashPassword(pw2, pw2hashed); 
    hashPassword(pw3, pw3hashed); 
    hashPassword(pw4, pw4hashed); 

    std::cout << pw1hashed << std::endl; 
    std::cout << pw2hashed << std::endl; 
    std::cout << pw3hashed << std::endl; 
    std::cout << pw4hashed << std::endl; 

    return 0; 
} 

Der Vorteil von diese Schnittstelle höherer Ebene ist, dass Sie einfach den EVP_sha256() Aufruf mit einer anderen Digest-Funktion austauschen müssen, z. EVP_sha512(), um einen anderen Digest zu verwenden. Es fügt also etwas Flexibilität hinzu.

Verwandte Themen