Calculate HMAC-SHA256 Digest Using User Defined Function in ColdFusion

Recently I am working on OpenID 2.0 protocol, in which I require HMAC-SHA256 (Hash Message Authentication Code – Secure Hash Algorithm using 256 bit key length) digest to generate Encrypted MAC key.

For that, I use following UDF HMAC_SHA256():

I wrote this function by taking reference from OpenID Consumer library.

Function Description

Purpose              : Calculates hash message authentication code using SHA256 algorithm.

Returns               : String (Encrypted MAC Key as string value)

Function syntax  : HMAC_SHA256(string Data, string Key [, numeric Bits])

Parameters         : 3 arguments required

  1. Data : a signature message
  2. Key   : a signature key
  3. Bits   : bit key length (Optional, Default value is 256) (For this function, Bits value must be 256)

Code of HMAC_SHA256() is look like:

[code:cf]<cffunction name="HMAC_SHA256" returntype="string" access="private" output="false" hint="Calculates hash message authentication code using SHA256 algorithm.">

  <cfargument name="Data" type="string" required="true" />
  <cfargument name="Key" type="string" required="true" />
  <cfargument name="Bits" type="numeric" required="false" default="256" />

  <cfset var i = 0 />
  <cfset var HexData = "" />
  <cfset var HexKey = "" />
  <cfset var KeyLen = 0 />
  <cfset var KeyI = "" />
  <cfset var KeyO = "" />

  <cfset HexData = BinaryEncode(CharsetDecode(Arguments.data, "iso-8859-1"), "hex") />
  <cfset HexKey = BinaryEncode(CharsetDecode(Arguments.key, "iso-8859-1"), "hex") />
  <cfset KeyLen = Len(HexKey)/2 />

  <cfif KeyLen gt 64>
     <cfset HexKey = Hash(CharsetEncode(BinaryDecode(HexKey, "hex"), "iso-8859-1"), "SHA-256", "iso-8859-1") />
     <cfset KeyLen = Len(HexKey)/2 />
  </cfif>

  <cfloop index="i" from="1" to="#KeyLen#">
     <cfset KeyI = KeyI & Right("0"&FormatBaseN(BitXor(InputBaseN(Mid(HexKey,2*i-1,2),16),InputBaseN("36",16)),16),2) />
     <cfset KeyO = KeyO & Right("0"&FormatBaseN(BitXor(InputBaseN(Mid(HexKey,2*i-1,2),16),InputBaseN("5c",16)),16),2) />
  </cfloop>

  <cfset KeyI = KeyI & RepeatString("36",64-KeyLen) />
  <cfset KeyO = KeyO & RepeatString("5c",64-KeyLen) />

  <cfset HexKey = Hash(CharsetEncode(BinaryDecode(KeyI&HexData, "hex"), "iso-8859-1"), "SHA-256", "iso-8859-1") />
  <cfset HexKey = Hash(CharsetEncode(BinaryDecode(KeyO&HexKey, "hex"), "iso-8859-1"), "SHA-256", "iso-8859-1") />

  <cfreturn Left(HexKey,arguments.Bits/4) />

</cffunction>[/code]

Hope this is helpful.