-1

When I pass the clear password to check the login of the user and apply a md5() on the string, the md5 hash is equal to the md5 hash stored in the MySQL database (Login succeed).

But I don't want to transfert the user password in clear inside my POST function, so I decided to use cryptoJS to only send the key and then decrypt the password on the PHP server side.

The problem is, when I'm using the decrypted password, the md5 is different. This is weird because the clear password string is the same than the decrypted password, and the md5 hash is different.

By doing:

 var_dump($clearPassword); //Hello.
 var_dump($decryptedPassword); //Hello.

But:

 var_dump(md5($clearPassword)); //3ea484671d7b00a1df4734ded1aa379c1.
 var_dump(md5($decryptedPassword)); //470a1ad08cbdebe075214591ea20fec9.

As you can see, it's exactly the same string but the md5 hash is different, I've noticed that var_dump() give as an output:

 string(16) for the $clearPassword;
 string(32) for the $decryptPassword;

I tried to change the string encoding but there's no luck. Anyone can explain me why md5() behave like that with those same passwords string? thanks again.

Gumbo
  • 643,351
  • 109
  • 780
  • 844
Nizar B.
  • 3,098
  • 9
  • 38
  • 56
  • Aren't you missing a '$' sign here `var_dump(md5(decryptedPassword))` – fpierrat Dec 28 '14 at 21:37
  • It's not at all clear what you mean by "only send the key and then decrypt the password on the PHP server side" - what key? What encryption are you using? (MD5 isn't encryption...) – Jon Skeet Dec 28 '14 at 21:37
  • @fpierrat Sorry, was a typo mistake, I amended it on my post, there's nothing to do with the $. – Nizar B. Dec 28 '14 at 21:38
  • @JonSkeet Basically, I'm writing a login system, when the user provide a clear password, I need to md5() the clear password and make a comparison with the md5 hash stored in my database. If it match it means the password is right. But instead of sending the clear password, I use cryptoJS to encrypt the clear password and send it to the PHP server. In my PHP code, I'm able to guess the clear password. Now i want to do the same process, I mean apply a md5() on the decrypted password to do the comparison, but the md5 is different even if the clear password match exactly the decrypted password. – Nizar B. Dec 28 '14 at 21:42
  • Well I suspect the clear password *isn't* exactly the same as the decrypted password, because of something in your encryption. But you haven't told us anything about how you're encrypting or decrypting. – Jon Skeet Dec 28 '14 at 21:44
  • 1
    why not hash the password to md5 clientside before transmitting it to the server? use a function like this one for instance: http://phpjs.org/functions/md5/ So you don't have to crypt/decrypt, you directly get what you have to compare to your base (I would even add a salt so that the client never sends the same value twice, like this http://stackoverflow.com/a/27555577/3872061 - it's the same idea, just with sha1 instead of md5) – fpierrat Dec 28 '14 at 21:44
  • 3
    Use [**CRYPT_BLOWFISH**](http://security.stackexchange.com/q/36471) or PHP 5.5's [`password_hash()`](http://www.php.net/manual/en/function.password-hash.php) function. For PHP < 5.5 use the [`password_hash() compatibility pack`](https://github.com/ircmaxell/password_compat). MD5 is old and considered broken. – Funk Forty Niner Dec 28 '14 at 21:47
  • @Fred-ii- Interesting, thanks I will have a look at it! – Nizar B. Dec 28 '14 at 21:56
  • The encryption/decryption routines are missing, as well as the code that retrieves the password. Those are required to answer this question well. I've got several hunches, but they stay guesswork without more info. – Maarten Bodewes Dec 29 '14 at 12:44

2 Answers2

3

the decrypted password IS NOT the same as the original. Check the length of the two strings, check the encoding, do a byte to byte comparison. "Hello\0" and "Hello \0" seems identical but they are not. Even "Hello\0" and "Hello\0\0\0" are not the same. Maybe the decryption algorithm gives a string length of 32 bytes.

Gianluca Ghettini
  • 11,129
  • 19
  • 93
  • 159
  • This is very interesting what you said, in fact I did a comparison byte per byte and it's completely different! Now I would like to know how I can make my two string (clear password + decrypted password) looks the same and have the same encoding structure? – Nizar B. Dec 28 '14 at 22:42
  • maybe one string is a plain ASCII string (C-string) the other is an utf16 or has another encoding schema. PHP is very tedious when it comes to string encoding, it doesn't tell you so much. – Gianluca Ghettini Dec 28 '14 at 22:44
  • You are right again! the cleared password is in ASCII and the decrypted one is UTF-8. I would like to know what to do, to get the same encoding ... – Nizar B. Dec 28 '14 at 22:46
  • you encryption-decryption algorithm should be ok, the string encoding is on top of that. Check how you transform the decoded data bytes into a new string (decodedPassword) – Gianluca Ghettini Dec 28 '14 at 22:49
  • I checked and I'm doing nothing with the encoding of my strings, the only thing that I know it's I have one witch is UTF-8 and another ASCII. This is the problem witch makes the md5 hash different even if the strings are exactly the same. – Nizar B. Dec 28 '14 at 23:05
  • ok, maybe your byte_to_string function (after decryption) is using utf-8 by default – Gianluca Ghettini Dec 28 '14 at 23:07
  • I'm not using byte to string only function like mysqli_real_escape_string(). And it doesn't matter, both are already different before any string function. – Nizar B. Dec 28 '14 at 23:08
  • here is the var_dump again: string(16) "SecretPassword" from the clear password. And string(32) "SecretPassword" from the decryption – Nizar B. Dec 28 '14 at 23:21
  • I still don't know how to makes the 2 strings have the same structure to get the same md5 hash. – Nizar B. Dec 29 '14 at 00:45
  • And pkcs padding in there? – Gianluca Ghettini Dec 29 '14 at 06:56
  • Sorry but what's PKCS ? – Nizar B. Dec 29 '14 at 12:34
  • PKCS is a pseudorandom padding added to the plaintext in order to randomize the encoding algorithm (i.e. to output different cipher texts while providing the same plain text) – Gianluca Ghettini Jan 02 '15 at 09:25
0

I'm probably going to do like @fpierrat said, just encrypt in the client side and do a straight comparison of md5 hash in the PHP server.

Nizar B.
  • 3,098
  • 9
  • 38
  • 56
  • 1
    Be careful, also add a random salt as explained on the other answer i was linking to... Otherwise, it means you simply send from client to server the exact string that is stored in your database (md5 of the password), which will then be strictly as secure as sending your password as clear text ;-) Same link again, to save time to eventually interested readers: http://stackoverflow.com/a/27555577/3872061 – fpierrat Dec 28 '14 at 22:00