Note: My friend uses hashing and encryption interchangeable in his argument. However, hashing is performed in the following code.
A friend of mine got a piece of PHP code before me and said that it was an amazing "encryption" method which used a randomized salt value to encrypt the password. Well, I asked that is something usually done, what is so amazing about it. He then, said that it was because the code did not store or use the salt but only used the hashed password value to verify it!
Initially, I smirked at that thought and then he decided to show me the code for it. It kind of looked as follows.
Hashing:
Here, the main focus is the crypt function which hashes the salt value and password.
Interesting part of his argument was in the verification code.
Verification:
So, the main argument, according to him, was that the verification used crypt function with only the hash value and initial password. No salt! He sounded super confident too!
Well, that kind of stumped me for a moment. It was against my traditional knowledge of crypto. How can the salt be random during hashing but the salt is never used in verification? So, I decided to dig a bit deeper.
At an initial glance, it looked to be legitimate, as we see that the verification only compares $pass with the output of crypt($password, $pass). Looking just at the hashed value did not help me much. It looked like this:
A friend of mine got a piece of PHP code before me and said that it was an amazing "encryption" method which used a randomized salt value to encrypt the password. Well, I asked that is something usually done, what is so amazing about it. He then, said that it was because the code did not store or use the salt but only used the hashed password value to verify it!
Initially, I smirked at that thought and then he decided to show me the code for it. It kind of looked as follows.
Hashing:
Here, the main focus is the crypt function which hashes the salt value and password.
Interesting part of his argument was in the verification code.
Verification:
So, the main argument, according to him, was that the verification used crypt function with only the hash value and initial password. No salt! He sounded super confident too!
Well, that kind of stumped me for a moment. It was against my traditional knowledge of crypto. How can the salt be random during hashing but the salt is never used in verification? So, I decided to dig a bit deeper.
At an initial glance, it looked to be legitimate, as we see that the verification only compares $pass with the output of crypt($password, $pass). Looking just at the hashed value did not help me much. It looked like this:
T$2a$10$.qckuIvEAfe8bb9lVLbBZuxvWJ7vAyyaSJ4ppAmc5C/wL38Vx7x86
This looked like a random value initially but then you see that $2a$10 was also appended to the base64 encoded random value in the code. This value actually became a part of the salt. Then printing out the salt made it all clear.
.qckuIvEAfe8bb9lVLbBZw==
16 characters of the salt were actually present in the hashed password. Only the "w==" values were not. As if it was truncated to 16 characters only. Running through few other iterations that returned a different salt and hashed value suggested the same thing. That meant crypt function internally only used 16 characters of the salt value and that is how the during verification the salt value was actually supplied to crypt. Now, it made complete sense. But wait, it is the exact same way as salted hashes work. It is also how linux stores its passwords in the /etc/shadow file.
The $2a specifies the algorithm used, in this case it is eksblowfish. $10 specifies the number of iterations used. Next 16 characters is the salt value as per crypt and the rest is the hashed value.
For further details about all the formats and algorithms used by linux systems to store passwords look here or at other online resources. Further details of how crypt function can be used for salted hashed is here.
The interesting thing was that this friend was technically very senior to me and this incident just made it more clear to me that not everyone understands crypto! He actually picked up the code from here and did not put some thought behind it. But, this was fun for me and probably educational for him 😉
No comments:
Post a Comment