IS.HASH.HMACSHA1: Generating HMAC-SHA1 Values with Generic MultiValue BASIC
With PHP, Python, and other languages, we can often find a complete answer - coded and ready - on the Internet. This article is part of an on-going effort to provide those sort of answers for MultiValue. Shared code is what makes any language easier to use.
The Message Authentication Code (MAC) is a widely used technique for performing message authentication. HMAC (short for "keyed-Hashing for Message Authentication") is a variation on the MAC algorithm. HMAC is currently an Internet draft that has been distributed by the Internet Engineering Task Force as Request For Proposal (RFP) 2104. It has emerged as an Internet standard for a variety of applications. SHA1 (Secure Hash Algorythm 1) is the hash we've selected for this example of HMAC.
MAC and HMAC are procedures that allow communicating parties to verify that received messages are authentic. The two important aspects are: (1) verifying that the contents of the message have not been altered and, (2) that the source is authentic. There are several different hash codes that HMAC uses: MD5, SHA-1, and SHA-256 are the most common.
The pseudocode below demonstrates how HMAC may be implemented. Block-size is 64 (bytes) when using one of the following hash functions: SHA-1, MD5, RIPEMD-128/160.
function hmac (key, message) if (length(key) > blocksize) then key = hash(key) // keys longer than blocksize are shortened end if if (length(key) < blocksize) then key = key || [0x00 * (blocksize - length(key))] // keys shorter than blocksize are zero-padded (where || is concatenation) end if o_key_pad = [0x5c * blocksize] || key // Where blocksize is that of the underlying hash function i_key_pad = [0x36 * blocksize] || key // Where || is exclusive or (XOR) return hash(o_key_pad || hash(i_key_pad || message)) // Where || is concatenation end function HMAC_SHA1("key", "The quick brown fox jumps over the lazy dog") = de7c9b85b8b78aa6bc8a7a36f70a90701c9db4d9
MultiValue BASIC Hashing
Most versions of MultiValue BASIC do not include built-in authentication hashing functions. This requires developers to create their own. It can be done in pure MultiValue BASIC, but you may see a performance hit, depending on how bit math is handled. For HMAC, the performance issues of generic bit math does not seem to be a problem.
This IS.HMACSHA1 implementation is dependent upon the IS.SHA1 hash subroutine. Be sure to download the appropriate version of this as well.
To keep this program generic across as many version of MultiValue BASIC, I chose to use bit math to do the logical AND and OR, instead of any built-in BITAND and BITOR found on some systems.
The code to replicate the Logical XOR needed in generating HMAC value was borrowed from Dave Meagher's excellent code found in the FOSS4MV/mvCrypt code on BitBucket:
HMAC.KEY = "key" HMAC.MSG = "The quick brown fox jumps over the lazy dog" CALL IS.HASH.HMACSHA1(HMAC.KEY,HMAC.MSG,HASH.VALUE) * TEST.VALUE = "de7c9b85b8b78aa6bc8a7a36f70a90701c9db4d9" CRT HASH.VALUE : " =" : TEST.VALUE :" - " IF (HASH.VALUE EQ TEST.VALUE) THEN CRT "Ok" END ELSE CRT "Failed" END Output
de7c9b85b8b78aa6bc8a7a36f70a90701c9db4d9 = de7c9b85b8b78aa6bc8a7a36f70a90701c9db4d9 - Ok