<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>