Question

Salt: can be anything.
Work factor: can be anything.
All of the following generate the same hash!

$pad = base64_decode('/gB=');
$data = array(
    'LegitimatePayload',
    'LaterSwitchedToMaliciousPayload',
    'Abracadabra',
    'hatIsGoingOn',
    'CanBeAlmostAnything',
);

foreach($data as $str){
    echo crypt($pad.$str, '$2a$04$AnySaltHere')."<br>\n";
}


Output:

$2a$04$AnySaltHere$$$$$$$$$$.m/QKi19jyBmSuP2VMcVuFRw.weCNRBa
$2a$04$AnySaltHere$$$$$$$$$$.m/QKi19jyBmSuP2VMcVuFRw.weCNRBa
$2a$04$AnySaltHere$$$$$$$$$$.m/QKi19jyBmSuP2VMcVuFRw.weCNRBa
$2a$04$AnySaltHere$$$$$$$$$$.m/QKi19jyBmSuP2VMcVuFRw.weCNRBa
$2a$04$AnySaltHere$$$$$$$$$$.m/QKi19jyBmSuP2VMcVuFRw.weCNRBa
$2a$04$AnySaltHere$$$$$$$$$$.m/QKi19jyBmSuP2VMcVuFRw.weCNRBa

Edit:
Here is a string that has the same first two bytes but has a different hash:
base64_decode('/gBQyoK71jVY/J7QuBNJuFdxyf2eTBCs42chkx6ZvpJYszpzg===')
If php stopped at first NUL byte, then how do you explain this?

Was it helpful?

Solution

All your strings have a prefix that will - when run through base64_decode - result in a 0xfe character and a 0x00 character with the extra - varying - characters after the 0x00. Since standard crypt will stop at a 0x00 character, all your crypt calls only encrypt the 0xfe character.

You can verify it by just calling

echo crypt("\376", '$2a$04$AnySaltHere')."<br>\n";

which will give the same result.

I'm assuming you used base64_decode by mistake meaning to actually call base64_encode.

Edit: As Roman points out, the string

"/gBQyoK71jVY/J7QuBNJuFdxyf2eTBCs42chkx6ZvpJYszpzg==="

will actually - despite the same prefix - crypt to something else entirely. This is due to that string actually being invalid base64 and base64_decode returning false. That results in the string crypt'ing to the same hash as the empty string does instead.

OTHER TIPS

You're not providing any valid base64 encoded strings, so base64_decode will probably just return false for all of your test cases, and thus it will encrypt them all the same. Why are you using base64_decode anyway?

You probably want base64_encode and not base64_decode. the reason it all returns the same is because the result is always false.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top