CSC 580: Cryptography and Security in Computing

Sample Code -- Computing Message Digests

This page contains examples of computing message digests in a variety of languages. The examples show the computation of a SHA-256 digest, but in all cases changing a single line of code will allow you to change that to SHA-1, SHA-512, or any of the other hash functions supported by that language and cryptographic library. Note that since HTML requires quoting of certain characters it may or may not work to copy and paste code from this page. To simplify matters, at the top of each code block is a link to the code that you can download (right click, "Save Link As..."). Examples are given below for C, C++, Java, C#, and Python.

Message Digests in C or C++

C and C++ do not have cryptographic functions in the standard language and library definitions, and cryptography is typically performed using the widely-distributed OpenSSL cryptographic library. If your system has the development version of these libraries installed (like the student-accessible UNCG linux host prdile.uncg.edu), then you can access the crypto functions such as message digests from C or C++ by including the header file <openssl/evp.h> - when you compile you will have to also tell the compiler to link in the crypto library, so to compile the code below you would use the command:

    gcc digest-in-c.c -lcrypto

C code: Download Link

#include <stdio.h>
#include <openssl/evp.h>

typedef unsigned char byte;

int main()
{
    EVP_MD_CTX ctx;
    const int DataLen = 30;
    byte digest[EVP_MAX_MD_SIZE];
    unsigned int outLen;
    int i;
    byte* testdata = (byte *)malloc(DataLen);

    for (i=0; i<DataLen; i++) testdata[i] = 0;

    EVP_DigestInit(&ctx, EVP_sha256());
    EVP_DigestUpdate(&ctx, testdata, DataLen);
    EVP_DigestFinal(&ctx, digest, &outLen);

    for (i=0; i<outLen; i++)
	printf("%02x", digest[i]);
    putchar('\n');

    return 0;
}

In C++ the technique is basically identical (you're using the same library, after all), but the command you use is "g++" rather than "gcc". I also changed the code to use C++ style output, although if I weren't trying to stay "pure C++" I would use the C-language output formatting function (printf) in the C++ code since I think it's a much nicer way of doing output.

C++ code: Download Link

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

using namespace std;

typedef unsigned char byte;

int main(int argc, char *argv[]) {
    const int DataLen = 30;
    EVP_MD_CTX ctx;
    byte digest[EVP_MAX_MD_SIZE];
    unsigned int outLen;

    byte* testdata = new byte[DataLen];
    for (int i=0; i<DataLen; i++) testdata[i] = 0;

    EVP_DigestInit(&ctx, EVP_sha256());
    EVP_DigestUpdate(&ctx, testdata, DataLen);
    EVP_DigestFinal(&ctx, digest, &outLen);

    for (unsigned int i=0; i<outLen; i++)
	cout << setfill('0') << setw(2) << hex << (int)digest[i];
    cout << dec << endl;

    return 0;
}

Message Digests in Java

Java does have some basic cryptography in the standard library, so the following code should work on any system. Unfortunately, I recently discovered that while the UNCG linux host has a Java runtime environment available, it does not have the compiler installed. This should work on any of the Windows-based lab machines though, through NetBeans or other Java development tools.

Java code: Download Link

import java.util.*;
import java.security.*;

public class Digest_in_Java {
    public static void main(String argv[]) {
	try {
	    MessageDigest md = MessageDigest.getInstance("SHA-256");
	    final int DataLen = 30;
	    byte[] testdata = new byte[DataLen];
	    byte[] digest = md.digest(testdata);

	    for (int i=0; i<digest.length; i++)
		System.out.format("%02x", digest[i]&0xff);
	    System.out.println();

	} catch (Exception e) {
	    System.out.println("Exception "+e);
	}
    }
}

Message Digests in C-Sharp

OK, just for fun I decided to see how this works in C#. Please keep in mind that this is the second C# program I have written in my life, and the first one just printed "Hello world"!!!

C# code: Download Link

using System.Security.Cryptography;

namespace DigestInCSharp
{
    class Program
    {
        static void Main(string[] args)
        {
            const int DataLen = 30;
            HashAlgorithm hash = HashAlgorithm.Create("SHA256");
            byte[] input = new byte[DataLen];
            byte[] digest = hash.ComputeHash(input);
            System.Console.WriteLine(System.BitConverter.ToString(digest));
        }
    }
}

Message Digests in Python

And finally, here's how you can compute message digests in Python. Note that the final call here is to "hexdigest" so that the produced value is a printable string. Most likely real code would use "digest" to get the actual digest rather than a printable string.

Python code: Download Link

import hashlib

d="\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
m = hashlib.sha256()
m.update(d)
print(m.hexdigest())