SHA256 using OpenSSL library (Linux)

I love cryptography and it was one of my favorite subjects in college. So recently when at work, I was asked to compute SHA256 for some data, I did some reading and learnt a lot of new stuff. I love learning anything new so enjoyed this exercise a lot. One of those days when work can be actually fun!

“A cryptographic hash (sometimes called ‘digest’) is a kind of ‘signature’ for a text or a data file. SHA-256 generates an almost-unique 256-bit (32-byte) signature for a text. A hash is not ‘encryption’ – it cannot be decrypted back to the original text (it is a ‘one-way’ cryptographic function, and is a fixed size for any size of source text). This makes it suitable when it is appropriate to compare ‘hashed’ versions of texts, as opposed to decrypting the text to obtain the original version. Such applications include stored passwords, challenge handshake authentication, and digital signatures.” (taken from here).

Sample program from Linux man page to compute SHA256:

    EVP_MD_CTX mdctx;
    const EVP_MD *md;
    char mess1[] = "Test Message\n";
    char mess2[] = "Hello World\n";
    unsigned char md_value[EVP_MAX_MD_SIZE];  
    //EVP_MAX_MD_SIZE = 64 (for SHA512 which is the max)
    int md_len, i;
    OpenSSL_add_all_digests();   //md = 0 and mdctx = junk
    md = EVP_get_digestbyname("SHA256");  // md gets valid values
    /*  md = 0x3dccd84540 
       *md = {type = 672, pkey_type = 668, md_size = 32, flags = 1036, init = 0x3dccac1820, update = 0x3dccac1810, final = 0x3dccac1800, copy = 0, cleanup = 0, sign = 0x3dcca9db20 , verify = 0x3dcca9dae0 , required_pkey_type = {6, 19, 0, 0, 0}, block_size = 64, ctx_size = 120, md_ctrl = 0}. 
       init, update, final, sign, verify are function pointers. */ 

    if(!md) {
       printf("Unknown message digest %s\n", argv[1]); 
    EVP_MD_CTX_init(&mdctx); //mdctx gets initialized. All the fields are set to 0. 
    EVP_DigestInit_ex(&mdctx, md, NULL); //Initialize mdctx using the values from md
    /* mdctx = {digest = 0x3dccd84540 (=md), engine = 0x0, flags = 0, md_data = 0x602f10, pctx = 0x0, update = 0x3dccac1810 (=md->update)} 

    EVP_DigestUpdate(&mdctx, mess1, strlen(mess1)); 
    EVP_DigestUpdate(&mdctx, mess2, strlen(mess2)); 
    EVP_DigestFinal_ex(&mdctx, md_value, &md_len); 
    /* md_value = {0x31, 0x8b, 0x20, 0xb8, 0x3a, 0x67, 0x30, 0xb9, 0x28, 0xc4, 0x61, 0x63, 0xa2, 0xa1, 0xce, 0xfe, 0xe4, 0x46, 0x61, 0x32, 0x73, 0x1c, 0x95, 0xc3, 0x96, 0x13, 0xac, 0xb5, 0x47, 0xcc, 0xb7, 0x15, 0xc2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0x7f, 0xe2, 0xff, 0xff, 0xff, 0x7f, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}
       md_len = 32 */

    EVP_MD_CTX_cleanup(&mdctx);  //reset mdctx fields
    /* mdctx = {digest = 0x0, engine = 0x0, flags = 0, md_data = 0x0, pctx = 0x0, update = 0} */
    printf("Digest is: ");
        for(i = 0; i < md_len; i++) printf("%02x", md_value[i]);
   // Digest is: 318b20b83a6730b928c46163a2a1cefee4466132731c95c39613acb547ccb715


  • Compile the above program using -lcrypto, to link OpenSSL library to your C file.
  • You will find the evp.h file in this path usually on Linux – /usr/include/openssl/evp.h. It has all the structure definitions.
  • You can find the OpenSSL library here on Linux – /usr/lib64/

To verify if your computation was right, use sha256sum tool:

$ sha256sum
Test Message  
Hello World   

318b20b83a6730b928c46163a2a1cefee4466132731c95c39613acb547ccb715  -

Useful links:

  4.  – it has a JavaScript implementation for SHA256

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s