Friday, August 07, 2015

Message in a Bottle

That's a Lot of Coffee!
My boss had a simple request.  He wanted some data-driven charts on our web server.  Since he required that the charts needed to be built once a day, I decided to build them as a batch process and upload them to the server.

We use Python extensively for batch processes, so I used numpy and matplotlib and build several graphics.  I talked to our IT people to enable FTP on the web server and was told no.

I looked into creating a user and transfer it over the network via the file system, but this plan failed as well.

So I built a web service and transferred the file over it, authenticating it by a  long password transferred over https.

Then IT applied a patch, and the crypto library Python used to connect via HTTPS could not longer establish a secure connection, and my task failed.

All I needed to do is transfer a public image.  There is nothing secret about the message I'm sending, I just needed some way to authenticate to make sure only I files I sent are written to the server.

There are two things I needed to validate.  First, the message came from me and that the message that came from me is the message received at the web server.

Enter HMAC.  An HMAC is a keyed message authentication hash.   It involves a shared secret between the sender and the receiver.  The sender creates a hash of the message (in my case the file and its file name) with the secret key.  This creates a one-way hash that we send along with the message.

The receiver reruns the hash with the message and checks to see the hash matches.  The only way it will match is if the secret key was mixed in and the message was unchanged.

Sender
Secret + Message = hash

Receiver
Message + secret =hash

Sample Code

So here is the hashing code in Dot Net
using System;
using System.Collections.Generic;
using System.Text;
using System.Security.Cryptography;
using System.IO;
    class Program
    {
        public static string ByteArrayToString(byte[] byte_Array)
        {
            StringBuilder hex = new StringBuilder(ba.Length * 2);
            foreach (byte b in byte_Array)
                hex.AppendFormat("{0:x2}", b);
            return hex.ToString();
        }
        static void Main(string[] args)
        {
            string SecretKey="this is a key";
            string Message ="this is a message";
            string netHexDigest=HMac(Message, SecretKey);
            Console.WriteLine(string.Format("    c#-{0}", netHexDigest ));
            Console.WriteLine("Done");
        }
        static string HMac(String Message, String Key)
        {
         
            byte[] byte_key = Encoding.ASCII.GetBytes(Key);
            HMACSHA1 HMAC = new HMACSHA1(byte_key);
            byte[] byte_Message = Encoding.ASCII.GetBytes(Message);
            using (MemoryStream ms = new MemoryStream(byte_Message))
            {
                byte[] Hash = HMAC.ComputeHash(ms);
                return ByteArrayToString(Hash);
            }
        }
    }
Here is the same code in Python
import hashlib
import hmac
secretKey='this is a key'
m=hmac.new(secretKey,'this is a message', hashlib.sha1) print m.hexdigest()

For more information: