Broken MD5 string representation

Giganews Newsgroups
Subject: Broken MD5 string representation
Posted by:  Christian Danner (-…@---.---)
Date: Mon, 14 May 2007

Hi,

after accidentally pressing the wrong button now the real thing:

With reference to MIDs <D3C2B4C1AD13E340nospam@tiscali.it> and
<C487130DE11BE340to_b…@yahoo.com> I take the liberty of asking what
the Indy developer's current POV is on the MD5 byte order issue. IMHO
APOP is broken with the implementation of HashStringAsHex() in the
latest Indy 10 version:

Text: <1776.8461756550120707484@mobile>omnimix
MD5 digest Indy server: 36cab241 b6e0d6ec a441824c 12e9f4a2
MD5 digest mail client: 41b2ca36 ecd6e0b6 4c8241a4 a2f4e912

.... which is why APOP connections get refused by the server.

RFC 1321 - The MD5 Message-Digest Algorithm - states:

------------------------------------------------------------
2. Terminology and Notation

  In this document a "word" is a 32-bit quantity and a "byte" is an
  eight-bit quantity. A sequence of bits can be interpreted in a
  natural manner as a sequence of bytes, where each consecutive group
  of eight bits is interpreted as a byte with the high-order (most
  significant) bit of each byte listed first. Similarly, a sequence
of
  bytes can be interpreted as a sequence of 32-bit words, where each
  consecutive group of four bytes is interpreted as a word with the
  low-order (least significant) byte given first.

....

3.5 Step 5. Output

  The message digest produced as output is A, B, C, D. That is, we
  begin with the low-order byte of A, and end with the high-order
byte
  of D.

------------------------------------------------------------

I see the cause of the problem in TIdHash.LongWordHashToHex():

function TIdHash.LongWordHashToHex(const AHash: TIdBytes; const
ACount: Integer): String;
var
  LValue: LongWord;
  I: Integer;
begin
  Result := '';
  for I := 0 to ACount-1 do begin
    LValue := BytesToLongWord(AHash, SizeOf(LongWord)*I);
    Result := Result + Sys.IntToHex(LValue, 8);
  end;
end;

Unlike SHA-1 MD5 determines a conversion of the single 32-bit register
values least significant byte first (e.g. $36cab241 => '41b2ca36'),
IntToHex() however returns them MSB first ($36cab241 => '36cab241').
So concerning MD5 IntToHex() is inappropriate and would have to be
replaced by a conversion routine that returns the 32-bit words
transformed into a sequence of bytes in reverse order (referring to
the current state of affairs).

Kind regards

Christian Danner @ ImhoTec

--
OmniMix .. protect your privacy
http://www.danner-net.de/om.htm

Replies