KNOWLEDGE BASE
Log In    |    Knowledge Base    |    4D Home
Tech Tip: Utility Method to Generate HMAC Hash
PRODUCT: 4D | VERSION: 20 | PLATFORM: Mac & Win
Published On: June 11, 2025

Below is a utility method to generate an HMAC hash using one of the algorithms in 4D:

// Method: Util_HMAC
//
// Description: Generates HMAC hash using specified algorithm from passed key and message
//
// Parameters:
// $key - Text, Secret Key
// $message - Text, Input Message
// $algorithm (OPTIONAL) - Integer, Algorithm using 4D Constants:
// - MD5 digest
// - SHA1 digest
// - SHA256 digest (DEFAULT)
// - SHA512 digest
//
// Output: $resultHash - Text
//
// Example:
// Util_HMAC("Hello"; "4D") // Returns "6CB54BDDCFFB127F89DADC7D77D7F9D1C63CD6FF3635027F6CCF23F426F3320C"
//
// Util_HMAC("Hello"; "4D"; SHA1 digest) // Returns "436056C4CA6E784D1DFAA813130C71C3563A47BB"
// ==========================================================================================

#DECLARE($key : Text; $message : Text; $algorithm : Integer)->$resultHash : Text

var $blockSize; $i : Integer
var $keyBlob; $messageBlob : Blob
var $innerKey; $outerKey; $innerHashBlob : Blob

// Default Algorithm
If (Count parameters<3)
   $algorithm:=SHA256 digest
End if

// Other 3 algorithims use 64 Block Size
If ($algorithm=SHA512 digest)
   $blockSize:=128
Else
   $blockSize:=64
End if

// Convert key and message to blobs
TEXT TO BLOB($key; $keyBlob; UTF8 text without length)
TEXT TO BLOB($message; $messageBlob; UTF8 text without length)

// Ensure key is block size
While (BLOB size($keyBlob)#$blockSize)
   If (BLOB size($keyBlob)>$blockSize)
   // Hash Key to reduce
     BASE64 DECODE(Generate digest($keyBlob; $algorithm; *); $keyBlob; *)
   Else
   // Pad key if it's too short
     SET BLOB SIZE($keyBlob; $blockSize; 0)
   End if
End while

// XOR key with inner and outer pads
SET BLOB SIZE($innerKey; $blockSize; 0)
SET BLOB SIZE($outerKey; $blockSize; 0)
For ($i; 0; $blockSize-1)
   $innerKey{$i}:=$keyBlob{$i} ^| 0x0036
   $outerKey{$i}:=$keyBlob{$i} ^| 0x005C
End for

// Compute inner hash
COPY BLOB($messageBlob; $innerKey; 0; BLOB size($innerKey); BLOB size($messageBlob))
BASE64 DECODE(Generate digest($innerKey; $algorithm; *); $innerHashBlob; *)

// Compute final HMAC-SHA256 hash
COPY BLOB($innerHashBlob; $outerKey; 0; BLOB size($outerKey); BLOB size($innerHashBlob))
$resultHash:=Generate digest($outerKey; $algorithm)