HMAC SHA1 and MD5

From ISXKB

Revision as of 10:49, 24 June 2013 by Ath (Talk | contribs)
(diff) ←Older revision | Current revision (diff) | Newer revision→ (diff)
Jump to: navigation, search

To perform a HMAC_SHA1 or HMAC_MD5 encoding, the following code can be used:

HMAC is explained here: Wikipedia HMAC Hash-based Message Authentication Code

// Output of both HMAC_ functions is a hex-string of the actual result, so you might need HexToBin() to create the actual binary result in a string
// Some support functions:

Function HexToBin(inp: AnsiString) : AnsiString;
var n : Integer;
Begin
    Result := '';
    n := 1;
    While n < Length(inp) do
    Begin
        Result := Result + Chr(StrToInt('$' + Copy(inp,n,2)));
        n := n + 2;
    End;
End; // HexToBin

Function Max(Left, Right : Int64) : Int64;
Begin
  If Left > Right then
    Result := Left
  Else
    Result := Right;
End; // Max

Function XorString(key, pad: AnsiString): AnsiString;
Var i : Integer;
    r : AnsiString;
Begin
  SetLength(r,Max(Length(key),Length(pad)));
  For i := 1 to Max(Length(key),Length(pad)) do
  Begin
    If (i <= Length(key)) and (i <= Length(pad)) Then
      r[i] := Chr(Ord(key[i]) xor Ord(pad[i]))
    Else
      if i > Length(key) then
        r[i] := pad[i]
      Else
        r[i] := key[i];
  End;
  Result := r;
End; // XorString

Const bs = 64; // According to https://en.wikipedia.org/wiki/Hash-based_message_authentication_code MD5 and SHA1 use a blocksize of 64

// The MD5 calculation:

Function HMAC_MD5(key, msg : AnsiString) : AnsiString;
Var i : Integer;
    o_key, i_key : AnsiString;
Begin
  if Length(key) > bs then HexToBin(GetMD5OfString(key));
  if Length(key) < bs then key := key + StringOfChar(#0,bs - Length(key));
  o_key := XorString(key,StringOfChar(#$5c,bs));
  i_key := XorString(key,StringOfChar(#$36,bs));
  Result := GetMD5OfString(o_key + HexToBin(GetMD5OfString(i_key + msg)));
End; // HMAC_MD5

// The SHA1 calculation:

Function HMAC_SHA1(key, msg : AnsiString) : AnsiString;
Var i : Integer;
    o_key, i_key : AnsiString;
Begin
  if Length(key) > bs then HexToBin(GetSHA1OfString(key));
  if Length(key) < bs then key := key + StringOfChar(#0,bs - Length(key));
  o_key := XorString(key,StringOfChar(#$5c,bs));
  i_key := XorString(key,StringOfChar(#$36,bs));
  Result := GetSHA1OfString(o_key + HexToBin(GetSHA1OfString(i_key + msg)));
End; // HMAC_SHA1

// My test code:

Procedure TestHMAC();
var p, r, s, t : AnsiString;
    key, msg : AnsiString;
Begin
  key := 'key';
  msg := 'The quick brown fox jumps over the lazy dog';
  r := HMAC_SHA1(key,msg);
  //r := HMAC_MD5(key,msg);
  p := 'de7c9b85b8b78aa6bc8a7a36f70a90701c9db4d9'; // SHA1
  t := '80070713463e7749b90c2dc24911e275'; // MD5
    if r = t then
      s := 'yes, MD5'
    else
    if r = p then
    begin
      s := 'yes, SHA1';
      t := p;
    end
    else
      s := 'no match';
  MsgBox('Test: key: "' + trim(key) + '" msg: "' + msg + '"'#13 + r + #13 + t + #13 + s,mbInformation,MB_OK);
End;

// End of code
Personal tools
Ads: