Background
SHA-256 is a cryptographic hash function developed by the US. National Security Agency (NSA) as a U.S. Federal Information Processing Standard (FIPS). The SHA acronym stands for Secure Hash Algorithm. A hash function operates on an arbitrary amount of data and returns a fixed-size bit string, the cryptographic hash value.
So why would such an algorithm be useful? Its utility lies in the fact that attempts to change the original data will almost certainly change the hash value returned by the algorithm. An obvious application would be to apply such an algorithm to a file (text or binary) as a means of determining whether or not it has been tampered with.
This post shows you how to use SHA-256 as implemented by the OpenSSL open source project, and use it within Windows / Visual C++ environments to produce digital signatures of strings or files.
Step 1: Download and install OpenSSL
See this web page for the list of all Win32-related implementations of OpenSSL. Specifically they recommend that you download and run the following executable as recommended for software developers by the creators of OpenSSL:
http://slproweb.com/download/Win32OpenSSL-1_0_1g.exe
Installing OpenSSL is straightfoward, but here are the screenshots showing the process of installing OpenSSL for Windows:
Step 2: Set up your Visual Studio environment
Here I use Visual Studio 2010, but there is no reason these instructions cannot be applied to earlier or later versions.
In Visual Studio create an empty project. Select File > New > Project. In the Visual C++ section select ‘Empty Project’ and give your project a name eg ‘SHA256’:
Right-click your project folder and select Properties > C/C++ > General.
Update the ‘Additional Include Directories’ section, so that your C++ project implementing the SHA-256 algorithm knows where to find the necessary header files:
Right-click your project folder and select Properties > Linker > Input.
Set the ‘Additional Dependencies’ section to include the ‘libeay32.lib’ library file:
Right-click your project folder and select Properties > Linker > General.
Set the ‘Additional Library Directories’ section to specify the location of the OpenSSL libraries:
Step 3: Try it!
All that remains is to try out the OpenSSL SHA-256 functionality with some sample code.
For this purpose I use some example code found on the StackOverflow site. Some very useful links here:
http://stackoverflow.com/questions/7853156/calculate-sha256-of-a-file-using-openssl-libcrypto-in-c
Sample code as follows:
#include <iostream> #include <sstream> #include <string> #include <iomanip> #include <stdio.h> #include <openssl/sha.h> #define _CRT_SECURE_NO_WARNINGS std::string sha256( const std::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); std::stringstream ss; for(int i = 0; i < SHA256_DIGEST_LENGTH; i++) { ss << std::hex << std::setw(2) << std::setfill('0') << (int)hash[i]; } return ss.str(); } 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; } int sha256_file(char* path, char output[65]) { FILE* file = fopen(path, "rb"); if(!file) return -1; unsigned char hash[SHA256_DIGEST_LENGTH]; SHA256_CTX sha256; SHA256_Init(&sha256); const int bufSize = 32768; char* buffer = new char[ bufSize ]; int bytesRead = 0; if(!buffer) return -1; while((bytesRead = fread(buffer, 1, bufSize, file))) { SHA256_Update(&sha256, buffer, bytesRead); } SHA256_Final(hash, &sha256); sha256_hash_string(hash, output); fclose(file); delete [] buffer; return 0; } int main() { // hash a string std::cout << "SHA-256 hash of \"Sample String\" text:" << std::endl; std::cout << sha256( "Sample String" ) << std::endl << std::endl; // hash a file std::cout << "SHA-256 hash of text file Hamlet.txt:" << std::endl; char calc_hash[65]; sha256_file( "Hamlet.txt", calc_hash ); std::cout << calc_hash << std::endl; return 0; }
Giving the following output:
Sample 'Hamlet.txt' text file can be downloaded here.