<div dir="ltr"><div class="gmail_extra"><div>Eureka!<br></div><div><br></div><div>After spending all day working on it, I finally did it! The pseudo steps are here: <a href="http://en.wikipedia.org/wiki/Hash-based_message_authentication_code" target="_blank">http://en.wikipedia.org/wiki/Hash-based_message_authentication_code</a></div>
<div><br></div><div>And, this is the final code (please improves it please):</div><div><br></div><div><div>uses</div><div> SHA1;</div><div><br></div><div>function SHA1Raw(const ABuffer; const ABufferLength: PtrUInt): string;</div>
<div>var</div><div> I: Byte;</div><div> VBytes : TBytes;</div><div> VDigest: TSHA1Digest;</div><div> VContext: TSHA1Context;</div><div>begin</div><div> Result := '';</div><div> SHA1Init(VContext);</div><div>
SHA1Update(VContext, ABuffer, ABufferLength);</div><div> SHA1Final(VContext, VDigest);</div><div> SetLength(VBytes, 20);</div><div> Move(VDigest, VBytes[0], 20);</div><div> for I := 0 to 19 do</div><div> Result := Result + Char(VBytes[I]);</div>
<div>end;</div><div><br></div><div>function HMACSHA1(const AKey, AMessage: string): string;</div><div>const</div><div> BLOCK_SIZE = 64;</div><div>var</div><div> I: Byte;</div><div> VKey: string;</div><div> VLenght: PtrUInt;</div>
<div> VOPadStr, VIPadStr: string;</div><div> VOPad, VIPad: array[1..BLOCK_SIZE] of Byte;</div><div>begin</div><div> VLenght := Length(AKey);</div><div> if VLenght > BLOCK_SIZE then</div><div> begin</div><div> SetLength(VKey, BLOCK_SIZE);</div>
<div> FillChar(Pointer(VKey)^, BLOCK_SIZE, #0);</div><div> VKey := SHA1Raw(Pointer(AKey)^, VLenght) + VKey;</div><div> end</div><div> else</div><div> begin</div><div> SetLength(VKey, BLOCK_SIZE - VLenght);</div>
<div> FillChar(Pointer(VKey)^, BLOCK_SIZE - VLenght, #0);</div><div> VKey := AKey + VKey;</div><div> end;</div><div> FillChar(VOPad, BLOCK_SIZE, $5c);</div><div> FillChar(VIPad, BLOCK_SIZE, $36);</div><div> for I := 1 to BLOCK_SIZE do</div>
<div> begin</div><div> VOPad[I] := VOPad[I] xor Byte(VKey[I]);</div><div> VIPad[I] := VIPad[I] xor Byte(VKey[I]);</div><div> end;</div><div> SetLength(VOPadStr, BLOCK_SIZE);</div><div> Move(VOPad, Pointer(VOPadStr)^, BLOCK_SIZE);</div>
<div> SetLength(VIPadStr, BLOCK_SIZE);</div><div> Move(VIPad, Pointer(VIPadStr)^, BLOCK_SIZE);</div><div> VIPadStr := VIPadStr + AMessage;</div><div> Result := SHA1Print(SHA1String(VOPadStr +</div><div> SHA1Raw(Pointer(VIPadStr)^, Length(VIPadStr))));</div>
<div>end;</div></div><div><br></div><div style>Usage:</div><div style><br></div><div style>WriteLn(HMACSHA1('key', 'The quick brown fox jumped over the lazy dog.')).</div><div style><br></div><div style>Result: 0b7252985d63555b31db4755f37efe218c509711 (same result in PHP, JS and Phyton! ;) )</div>
<div style><br></div><div style>So, can you add this code (I'll make HMACMD5 too) in FCL hashes? (>fpc\VER\source\packages\hash\src)</div><div style><br></div><div style>Thank you very much buddies! :)</div><div><br>
</div>-- <br>Silvio Clécio<br>My public projects - <a href="http://github.com/silvioprog" target="_blank">github.com/silvioprog</a>
</div></div>