8

I'm using Delphi XE2 with FireMonkey.

I have read many other questions about MD5 but didn't find an answer to the issue I have... I've also tested different scripts to generate a MD5 from Delphi:

function MD5(const text: string) : string;
var
  md5 : TIdHashMessageDigest5;
begin
  md5    := TIdHashMessageDigest5.Create;
  Result := LowerCase(md5.HashStringAsHex(text, TEncoding.ANSI));
  md5.Free;
end;

or

function MD5(const text: String) : string;
var
  md5: IMD5;
begin
  md5:= GetMD5;
  md5.Init;
  md5.Update(TByteDynArray(RawByteString(AnsiString(text))), Length(AnsiString(text)));
  Result := LowerCase(md5.AsString);
end;

Both give me the same results... which is often the same I have within PHP:

$md5 = md5($toencode);
$md5 = hash("md5", $toencode);

But the results are different if I use Delphi or PHP, when I request the MD5 of one of these chars: " or ' There are maybe others chars which generate different results but I just find these ones during my tests...

I have tested with many extended ASCII characters and have the same MD5...

So, I don't understand why I have differences with few of them (" or ' ), and I'd like to know if there's a way to always generate the PHP MD5 result from Delphi, whatever the chars are.

Any idea?

For instance:

with Delphi:

": b15835f133ff2e27c7cb28117bfae8f4

': 3590cb8af0bbb9e78c343b52b93773c9

with PHP:

": 3bd864034f446da13581129bb17f9191

': 024c94d6e03b6f67a86b952b914816c7

Formalizing this question.. I've find the answer... BTW, I post it as others may have the same issue...

" and ' are escaped in PHP... so, within Delphi, I have to encode \" and \'... if you think I have forgotten chars or if you want to add some details, do not hesitate...

Tchoupi
  • 14,560
  • 5
  • 37
  • 71
Whiler
  • 7,998
  • 4
  • 32
  • 56
  • 1
    You can probably run stripslashes in PHP before MD5ing – Jason Oct 05 '12 at 13:00
  • 1
    Yes... but.. ;o) I'm accessing a remote server where I don't have access to the code... – Whiler Oct 05 '12 at 13:01
  • 2
    PHP escapes quote, double quote, backslash and 'NUL' (which is `#0` in Delphi I guess), see http://www.php.net/manual/en/security.magicquotes.what.php – Stijn Sanders Oct 05 '12 at 13:46
  • 1
    You do not calculate hashes on strings, but on binary data. Now go sit somewhere, and write that down 100 times. – Jeroen Wiert Pluimers Oct 05 '12 at 21:20
  • @JeroenWiertPluimers: I agree with you... but when an API demands a MD5 password... to use the API... you need to do some compromise ;) – Whiler Oct 07 '12 at 00:30
  • 1
    Then you must make sure the password is encoded the same binary way at both sides. That's the crux of your problem. The only relevance of MD5 here is that it shows you got your encoding wrong. In this case: because you were escaping things that should not have been. – Jeroen Wiert Pluimers Oct 07 '12 at 06:28

3 Answers3

6

Delphi is in the right here.

>>> hashlib.md5('"').hexdigest()
'b15835f133ff2e27c7cb28117bfae8f4'
>>> hashlib.md5("'").hexdigest()
'3590cb8af0bbb9e78c343b52b93773c9'

PHP should not need those characters escaped by default; make sure that it is configured to not do so.

Ignacio Vazquez-Abrams
  • 776,304
  • 153
  • 1,341
  • 1,358
3

The PHP hash function implements MD5 perfectly well.

The following PHP:

$md5 = hash("md5", "\"");
echo "\":&nbsp;&nbsp;", $md5, "<br/>";
$md5 = hash("md5", "'");
echo "':&nbsp;&nbsp;", $md5, "<br/>";
$md5 = hash("md5", "\\\"");
echo "\\\": ", $md5, "<br/>";
$md5 = hash("md5", "\\'");
echo "\\': ", $md5, "<br/>";

results in this output:

":  b15835f133ff2e27c7cb28117bfae8f4
':  3590cb8af0bbb9e78c343b52b93773c9
\": 3bd864034f446da13581129bb17f9191
\': 024c94d6e03b6f67a86b952b914816c7

So, the top two values are what you get from your Delphi code, and the same values that Ignacio obtained from Python. So, there's absolutely no reason to believe that the PHP MD5 code is at fault. And the bottom two values are what your PHP code is returning.

Which leaves us to conclude that you are feeding your Delphi code different input from that which you feed to your PHP code. If you feed them both the same input, you will get the same output.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • Yes.. My bad... @StijnSanders's URL explained me the reason... My tests were wrong cause the variables which were filled from a `form`were _corrupted_ ([escaped with a backslash automatically](http://www.php.net/manual/en/security.magicquotes.what.php)). – Whiler Oct 07 '12 at 00:38
1
    uses IdHashMessageDigest;

    function MD5(const texto:string):string;
    var
      idmd5 : TIdHashMessageDigest5;
    begin
      idmd5 := TIdHashMessageDigest5.Create;
      try
        result := idmd5.HashStringAsHex(UTF8Encode(texto));
      finally
        idmd5.Free;
      end;
    end;

To exactly identical use LowerCase(MD5('1234')); this is identical with PHP MD5.

Jessé Catrinck
  • 2,227
  • 19
  • 20