Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- {
- This file is part of the Free Component Library.
- Hash-based supporting HMAC-MD5 and HMAC-SHA-1.
- Copyright (c) 2013 by Silvio Clecio silvioprog@gmail.com
- See the file COPYING.FPC, included in this distribution,
- for details about the copyright.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- }
- unit HMAC;
- {$mode objfpc}{$H+}
- interface
- uses
- MD5, SHA1;
- type
- THMACMD5Digest = TMD5Digest;
- THMACSHA1Digest = TSHA1Digest;
- function HMACMD5Digest(const AKey, AMessage: string): THMACMD5Digest;
- function HMACMD5Print(const ADigest: THMACMD5Digest): string;
- function HMACMD5(const AKey, AMessage: string): string;
- function HMACSHA1Digest(const AKey, AMessage: string): THMACSHA1Digest;
- function HMACSHA1Print(const ADigest: THMACSHA1Digest): string;
- function HMACSHA1(const AKey, AMessage: string): string;
- implementation
- const
- HEX_TABLE: array[0..15] of Char = '0123456789abcdef';
- MD5_BLOCK_SIZE = 64;
- MD5_BLOCK_COUNT = 16;
- SHA1_BLOCK_SIZE = 64;
- SHA1_BLOCK_COUNT = 20;
- function MD5Raw(var ABuffer; const ABufferLength: PtrUInt): string;
- var
- I: Byte;
- VDest: PChar;
- VDigest: TMD5Digest;
- VContext: TMD5Context;
- begin
- MD5Init(VContext);
- MD5Update(VContext, ABuffer, ABufferLength);
- MD5Final(VContext, VDigest);
- SetLength(Result, MD5_BLOCK_COUNT);
- VDest := Pointer(Result);
- for I := 0 to MD5_BLOCK_COUNT - 1 do
- begin
- VDest^ := Char(VDigest[I]);
- Inc(VDest);
- end;
- end;
- function HMACMD5Digest(const AKey, AMessage: string): THMACMD5Digest;
- var
- VLenght: PtrUInt;
- PKey, POPad, PIPad: PChar;
- VKey, VOPad, VIPad: string;
- begin
- VLenght := Length(AKey);
- if VLenght > MD5_BLOCK_SIZE then
- begin
- SetLength(VKey, MD5_BLOCK_SIZE);
- FillChar(Pointer(VKey)^, MD5_BLOCK_SIZE, #0);
- VKey := MD5Raw(Pointer(AKey)^, VLenght) + VKey;
- end
- else
- begin
- SetLength(VKey, MD5_BLOCK_SIZE - VLenght);
- FillChar(Pointer(VKey)^, MD5_BLOCK_SIZE - VLenght, #0);
- VKey := AKey + VKey;
- end;
- SetLength(VOPad, MD5_BLOCK_SIZE);
- POPad := PChar(VOPad);
- FillChar(POPad^, MD5_BLOCK_SIZE, $5c);
- SetLength(VIPad, MD5_BLOCK_SIZE);
- PIPad := PChar(VIPad);
- FillChar(PIPad^, MD5_BLOCK_SIZE, $36);
- PKey := PChar(VKey);
- while PKey^ <> #0 do
- begin
- POPad^ := Char(Ord(POPad^) xor Ord(PKey^));
- PIPad^ := Char(Ord(PIPad^) xor Ord(PKey^));
- Inc(POPad);
- Inc(PIPad);
- Inc(PKey);
- end;
- VIPad := VIPad + AMessage;
- Result := MD5String(VOPad + MD5Raw(Pointer(VIPad)^, Length(VIPad)));
- end;
- function HMACMD5Print(const ADigest: THMACMD5Digest): string;
- var
- I: Byte;
- VDest: PChar;
- begin
- SetLength(Result, MD5_BLOCK_COUNT * 2);
- VDest := Pointer(Result);
- for I := 0 to MD5_BLOCK_COUNT - 1 do
- begin
- VDest[0] := HEX_TABLE[(ADigest[I] shr 4) and 15];
- VDest[1] := HEX_TABLE[ADigest[I] and 15];
- Inc(VDest, 2);
- end;
- end;
- function HMACMD5(const AKey, AMessage: string): string;
- begin
- Result := HMACMD5Print(HMACMD5Digest(AKey, AMessage));
- end;
- function SHA1Raw(const ABuffer; const ABufferLength: PtrUInt): string;
- var
- I: Byte;
- VDest: PChar;
- VDigest: TSHA1Digest;
- VContext: TSHA1Context;
- begin
- SHA1Init(VContext);
- SHA1Update(VContext, ABuffer, ABufferLength);
- SHA1Final(VContext, VDigest);
- SetLength(Result, SHA1_BLOCK_COUNT);
- VDest := Pointer(Result);
- for I := 0 to SHA1_BLOCK_COUNT - 1 do
- begin
- VDest^ := Char(VDigest[I]);
- Inc(VDest);
- end;
- end;
- function HMACSHA1Digest(const AKey, AMessage: string): THMACSHA1Digest;
- var
- VLenght: PtrUInt;
- PKey, POPad, PIPad: PChar;
- VKey, VOPad, VIPad: string;
- begin
- VLenght := Length(AKey);
- if VLenght > SHA1_BLOCK_SIZE then
- begin
- SetLength(VKey, SHA1_BLOCK_SIZE);
- FillChar(Pointer(VKey)^, SHA1_BLOCK_SIZE, #0);
- VKey := SHA1Raw(Pointer(AKey)^, VLenght) + VKey;
- end
- else
- begin
- SetLength(VKey, SHA1_BLOCK_SIZE - VLenght);
- FillChar(Pointer(VKey)^, SHA1_BLOCK_SIZE - VLenght, #0);
- VKey := AKey + VKey;
- end;
- SetLength(VOPad, SHA1_BLOCK_SIZE);
- POPad := PChar(VOPad);
- FillChar(POPad^, SHA1_BLOCK_SIZE, $5c);
- SetLength(VIPad, SHA1_BLOCK_SIZE);
- PIPad := PChar(VIPad);
- FillChar(PIPad^, SHA1_BLOCK_SIZE, $36);
- PKey := PChar(VKey);
- while PKey^ <> #0 do
- begin
- POPad^ := Char(Ord(POPad^) xor Ord(PKey^));
- PIPad^ := Char(Ord(PIPad^) xor Ord(PKey^));
- Inc(POPad);
- Inc(PIPad);
- Inc(PKey);
- end;
- VIPad := VIPad + AMessage;
- Result := SHA1String(VOPad + SHA1Raw(Pointer(VIPad)^, Length(VIPad)));
- end;
- function HMACSHA1Print(const ADigest: THMACSHA1Digest): string;
- var
- I: Byte;
- VDest: PChar;
- begin
- SetLength(Result, SHA1_BLOCK_COUNT * 2);
- VDest := Pointer(Result);
- for I := 0 to SHA1_BLOCK_COUNT - 1 do
- begin
- VDest[0] := HEX_TABLE[(ADigest[I] shr 4) and 15];
- VDest[1] := HEX_TABLE[ADigest[I] and 15];
- Inc(VDest, 2);
- end;
- end;
- function HMACSHA1(const AKey, AMessage: string): string;
- begin
- Result := HMACSHA1Print(HMACSHA1Digest(AKey, AMessage));
- end;
- end.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement