Advertisement
Guest User

Untitled

a guest
Mar 24th, 2013
40
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Pascal 5.13 KB | None | 0 0
  1. {
  2.   This file is part of the Free Component Library.
  3.  
  4.   Hash-based supporting HMAC-MD5 and HMAC-SHA-1.
  5.   Copyright (c) 2013 by Silvio Clecio silvioprog@gmail.com
  6.  
  7.   See the file COPYING.FPC, included in this distribution,
  8.   for details about the copyright.
  9.  
  10.   This program is distributed in the hope that it will be useful,
  11.   but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  13. }
  14.  
  15. unit HMAC;
  16.  
  17. {$mode objfpc}{$H+}
  18.  
  19. interface
  20.  
  21. uses
  22.   MD5, SHA1;
  23.  
  24. type
  25.   THMACMD5Digest = TMD5Digest;
  26.   THMACSHA1Digest = TSHA1Digest;
  27.  
  28. function HMACMD5Digest(const AKey, AMessage: string): THMACMD5Digest;
  29. function HMACMD5Print(const ADigest: THMACMD5Digest): string;
  30. function HMACMD5(const AKey, AMessage: string): string;
  31. function HMACSHA1Digest(const AKey, AMessage: string): THMACSHA1Digest;
  32. function HMACSHA1Print(const ADigest: THMACSHA1Digest): string;
  33. function HMACSHA1(const AKey, AMessage: string): string;
  34.  
  35. implementation
  36.  
  37. const
  38.   HEX_TABLE: array[0..15] of Char = '0123456789abcdef';
  39.   MD5_BLOCK_SIZE = 64;
  40.   MD5_BLOCK_COUNT = 16;
  41.   SHA1_BLOCK_SIZE = 64;
  42.   SHA1_BLOCK_COUNT = 20;
  43.  
  44. function MD5Raw(var ABuffer; const ABufferLength: PtrUInt): string;
  45. var
  46.   I: Byte;
  47.   VDest: PChar;
  48.   VDigest: TMD5Digest;
  49.   VContext: TMD5Context;
  50. begin
  51.   MD5Init(VContext);
  52.   MD5Update(VContext, ABuffer, ABufferLength);
  53.   MD5Final(VContext, VDigest);
  54.   SetLength(Result, MD5_BLOCK_COUNT);
  55.   VDest := Pointer(Result);
  56.   for I := 0 to MD5_BLOCK_COUNT - 1 do
  57.   begin
  58.     VDest^ := Char(VDigest[I]);
  59.     Inc(VDest);
  60.   end;
  61. end;
  62.  
  63. function HMACMD5Digest(const AKey, AMessage: string): THMACMD5Digest;
  64. var
  65.   VLenght: PtrUInt;
  66.   PKey, POPad, PIPad: PChar;
  67.   VKey, VOPad, VIPad: string;
  68. begin
  69.   VLenght := Length(AKey);
  70.   if VLenght > MD5_BLOCK_SIZE then
  71.   begin
  72.     SetLength(VKey, MD5_BLOCK_SIZE);
  73.     FillChar(Pointer(VKey)^, MD5_BLOCK_SIZE, #0);
  74.     VKey := MD5Raw(Pointer(AKey)^, VLenght) + VKey;
  75.   end
  76.   else
  77.   begin
  78.     SetLength(VKey, MD5_BLOCK_SIZE - VLenght);
  79.     FillChar(Pointer(VKey)^, MD5_BLOCK_SIZE - VLenght, #0);
  80.     VKey := AKey + VKey;
  81.   end;
  82.   SetLength(VOPad, MD5_BLOCK_SIZE);
  83.   POPad := PChar(VOPad);
  84.   FillChar(POPad^, MD5_BLOCK_SIZE, $5c);
  85.   SetLength(VIPad, MD5_BLOCK_SIZE);
  86.   PIPad := PChar(VIPad);
  87.   FillChar(PIPad^, MD5_BLOCK_SIZE, $36);
  88.   PKey := PChar(VKey);
  89.   while PKey^ <> #0 do
  90.   begin
  91.     POPad^ := Char(Ord(POPad^) xor Ord(PKey^));
  92.     PIPad^ := Char(Ord(PIPad^) xor Ord(PKey^));
  93.     Inc(POPad);
  94.     Inc(PIPad);
  95.     Inc(PKey);
  96.   end;
  97.   VIPad := VIPad + AMessage;
  98.   Result := MD5String(VOPad + MD5Raw(Pointer(VIPad)^, Length(VIPad)));
  99. end;
  100.  
  101. function HMACMD5Print(const ADigest: THMACMD5Digest): string;
  102. var
  103.   I: Byte;
  104.   VDest: PChar;
  105. begin
  106.   SetLength(Result, MD5_BLOCK_COUNT * 2);
  107.   VDest := Pointer(Result);
  108.   for I := 0 to MD5_BLOCK_COUNT - 1 do
  109.   begin
  110.     VDest[0] := HEX_TABLE[(ADigest[I] shr 4) and 15];
  111.     VDest[1] := HEX_TABLE[ADigest[I] and 15];
  112.     Inc(VDest, 2);
  113.   end;
  114. end;
  115.  
  116. function HMACMD5(const AKey, AMessage: string): string;
  117. begin
  118.   Result := HMACMD5Print(HMACMD5Digest(AKey, AMessage));
  119. end;
  120.  
  121. function SHA1Raw(const ABuffer; const ABufferLength: PtrUInt): string;
  122. var
  123.   I: Byte;
  124.   VDest: PChar;
  125.   VDigest: TSHA1Digest;
  126.   VContext: TSHA1Context;
  127. begin
  128.   SHA1Init(VContext);
  129.   SHA1Update(VContext, ABuffer, ABufferLength);
  130.   SHA1Final(VContext, VDigest);
  131.   SetLength(Result, SHA1_BLOCK_COUNT);
  132.   VDest := Pointer(Result);
  133.   for I := 0 to SHA1_BLOCK_COUNT - 1 do
  134.   begin
  135.     VDest^ := Char(VDigest[I]);
  136.     Inc(VDest);
  137.   end;
  138. end;
  139.  
  140. function HMACSHA1Digest(const AKey, AMessage: string): THMACSHA1Digest;
  141. var
  142.   VLenght: PtrUInt;
  143.   PKey, POPad, PIPad: PChar;
  144.   VKey, VOPad, VIPad: string;
  145. begin
  146.   VLenght := Length(AKey);
  147.   if VLenght > SHA1_BLOCK_SIZE then
  148.   begin
  149.     SetLength(VKey, SHA1_BLOCK_SIZE);
  150.     FillChar(Pointer(VKey)^, SHA1_BLOCK_SIZE, #0);
  151.     VKey := SHA1Raw(Pointer(AKey)^, VLenght) + VKey;
  152.   end
  153.   else
  154.   begin
  155.     SetLength(VKey, SHA1_BLOCK_SIZE - VLenght);
  156.     FillChar(Pointer(VKey)^, SHA1_BLOCK_SIZE - VLenght, #0);
  157.     VKey := AKey + VKey;
  158.   end;
  159.   SetLength(VOPad, SHA1_BLOCK_SIZE);
  160.   POPad := PChar(VOPad);
  161.   FillChar(POPad^, SHA1_BLOCK_SIZE, $5c);
  162.   SetLength(VIPad, SHA1_BLOCK_SIZE);
  163.   PIPad := PChar(VIPad);
  164.   FillChar(PIPad^, SHA1_BLOCK_SIZE, $36);
  165.   PKey := PChar(VKey);
  166.   while PKey^ <> #0 do
  167.   begin
  168.     POPad^ := Char(Ord(POPad^) xor Ord(PKey^));
  169.     PIPad^ := Char(Ord(PIPad^) xor Ord(PKey^));
  170.     Inc(POPad);
  171.     Inc(PIPad);
  172.     Inc(PKey);
  173.   end;
  174.   VIPad := VIPad + AMessage;
  175.   Result := SHA1String(VOPad + SHA1Raw(Pointer(VIPad)^, Length(VIPad)));
  176. end;
  177.  
  178. function HMACSHA1Print(const ADigest: THMACSHA1Digest): string;
  179. var
  180.   I: Byte;
  181.   VDest: PChar;
  182. begin
  183.   SetLength(Result, SHA1_BLOCK_COUNT * 2);
  184.   VDest := Pointer(Result);
  185.   for I := 0 to SHA1_BLOCK_COUNT - 1 do
  186.   begin
  187.     VDest[0] := HEX_TABLE[(ADigest[I] shr 4) and 15];
  188.     VDest[1] := HEX_TABLE[ADigest[I] and 15];
  189.     Inc(VDest, 2);
  190.   end;
  191. end;
  192.  
  193. function HMACSHA1(const AKey, AMessage: string): string;
  194. begin
  195.   Result := HMACSHA1Print(HMACSHA1Digest(AKey, AMessage));
  196. end;
  197.  
  198. end.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement