Software Secret Weapons™  
MD5 For AJAX posted by Pavel Simakov on 2007-05-07 16:14:30 under AJAX
view comments
 


MD5 is a widely-used cryptographic hash function. Recently, I used MD5 to create digital signatures in one of my AJAX gaming projects. In my project, the MD5 signatures are generated from several platforms and virtual machines including PHP, Java, JavaScript and C#. I was not sure if MD5 libraries exist for all of them and how to use these libraries to generate identical signatures.

The variety of good quality MD5 implementations exists for any language you can imagine. Now, I just needed to pull all those libraries together in one place and check that they all work and produce identical signatures in my AJAX project. All seemed fine until I hit a small snug. There are two different ways to create MD5 signatures: without a key, or using a key. Some MD5 implementations (MySQL 5.0, for example) do not support signing with a key. Why do I need signing with a key? This is not obvious, but signing with the key is very useful as it makes it so much harder to reverse the MD5 signature. Warning: please make sure that you understand what MD5 is and is not before using it in your projects. MD5 is not an encryption algorithm, but rather a one-way hash function; thus it has some, but very limited utility in providing true client/server secure communication.

After some looking around and help from one of my friends, I have collected the code snippets for MD5 signing of text with the key for PHP, Java, JavaScript (and ActionScript). Now I can cryptographically sign some text in the AJAX application using JavaScript (or in the Flash Movie using ActionScript). The signature can then be sent to a server and verified in either PHP or Java. Or in reverse, the server can send a signature that client can verify in the browser. All examples below sign the word "foo" with the key "bar" to produce a signature: 31b6db9e5eb4addb42f1a6ca07367adc. Enjoy!

For PHP
Make sure that your version of PHP is complied with mhash support (very like it already is). Notice that in the mhash() function the key parameter comes after the message parameter. Now you can create digital signatures with key like this:


<?php
	$sign = bin2hex(mhash(MHASH_MD5, "foo", "bar"));
	echo $sign;
?>

If function mhash() is not available in your PHP setting, here is an alternative:


<?php
	// RFC 2104 HMAC implementation for php.
	// Creates an md5 HMAC.
	// Eliminates the need to install mhash to compute a HMAC
	// Hacked by Lance Rushing
	function hmac ($key, $data){
	   $b = 64; // byte length for md5
	   if (strlen($key) > $b) {
		   $key = pack("H*",md5($key));
	   }

	   $key  = str_pad($key, $b, chr(0x00));
	   $ipad = str_pad('', $b, chr(0x36));
	   $opad = str_pad('', $b, chr(0x5c));
	   $k_ipad = $key ^ $ipad ;
	   $k_opad = $key ^ $opad;
	   return md5($k_opad  . pack("H*",md5($k_ipad . $data)));
	}
?>

For JavaScript
Download JavaScript implementation of MD5 algorithm from Paul Johnston and link it to your AJAX application. Notice that in the hex_hmac_md5() function the key parameter comes before the message parameter. Now you can create digital signatures with key like this:


<script src="md5.js"></script>

<script language="JavaScript">
	var sign = hex_hmac_md5("bar", "foo");
	alert(sign);
</script>

For Java (1.4.2+)
No need for any libraries, Java SDK 1.4.2+ already has all you need. Notice that in the string2md5HMA() function the key parameter comes before the message parameter. Here is how to create MD5 signatures with key in Java:


import java.security.Provider;
import java.security.Security;

import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

public class MyMD5 {

    public static String string2md5HMA(String keyString, String message)  {
	Provider sunJce = new com.sun.crypto.provider.SunJCE();
        Security.insertProviderAt(sunJce,0);
        SecretKey key = new SecretKeySpec(keyString.getBytes(), "HmacMD5");
        try {
		Mac mac = Mac.getInstance("HmacMD5");
		mac.init(key);
		return toHEX(mac.doFinal(message.getBytes())); 
        } catch (Exception e) { 
		throw new RuntimeException("Failed to create signature", e);
        }
    }
    
    private static String toHEX(byte[] digest) {
        StringBuffer hexString = new StringBuffer();
        for (int i = 0; i < digest.length; ++i) { 
		String hx = Integer.toHexString(0xFF & digest[i]); 
		if (hx.length() == 1) { 
			hx = "0" + hx; 
		} 
		hexString.append(hx); 
        }
        return hexString.toString();
    } 
    
    public static void main(String [] args){
		System.out.println(string2md5HMA("bar", "foo"));
    }	
}

No comments yet


Leave a comment


  Copyright © 2004-2007 by Pavel Simakov SourceForge.net Logo