Generate sha256 with OpenSSL and C++ Generate sha256 with OpenSSL and C++ unix unix

Generate sha256 with OpenSSL and C++


Here's how I did it:

void sha256_hash_string (unsigned 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;}void sha256_string(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;    unsigned char hash[SHA256_DIGEST_LENGTH];    SHA256_CTX sha256;    SHA256_Init(&sha256);    const int bufSize = 32768;    unsigned char *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;}

It's called like this:

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


std based

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


Using OpenSSL's EVP interface (the following is for 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;}

The advantage of this higher level interface is that you simply need to swap out the EVP_sha256() call with another digest's function, e.g. EVP_sha512(), to use a different digest. So it adds some flexibility.