patrickfav/bcrypt

Strange and Incorrect Hash Output

scothampelold opened this issue · 2 comments

I am porting an old application of mine from PHP to a personal Java android application. My PHP application creates a BCrypt hash and so I am using your library for this functionality in the app.

Given the salt of $2a$10$bf2a37d5e83e612cdfeebec9e2e71a318e9767cd3e035f4b8ed73eecf2ae8110b3aa3f3688874f7cfae8cb49474369e74cdde7dba7bddf84f0c5f6fc56013715 (I know, it's formatted like a hash, it's old code that I wrote weirdly. But this is 100% the salt), and a password of prof.siko with 10 rounds in the PHP password_hash() function, the returned hash is $2y$10$JDJhJDEwJGJmMmEzN2Q1ZO/Dil6rDX7EQIetkSEj6ZUH.yRJpfezm. I can only assume this function takes trims the extra salt characters not required by the function because of the base64 encoded salt within the returned hash.

I expected the same functionality with your library, yet did not receive it.

I am using the command BCrypt.withDefaults().hash(cost, salt.getBytes(StandardCharsets.UTF_8), password.getBytes(StandardCharsets.UTF_8)) where the salt variable is $2a$10$bf2a37d5e and the password variable is prof.siko. The same as in my PHP tests. This command, however, returns the hash $2a$10$HBHfHBCuHEHkKkCxL0OzXO.9qaZyVOYZO55fiE8ev5Wa2adkFQ0au.

The interesting aspect of this problem to me is the fact that most of the base64 encoded salt portion of the hash produced by your library is shifted down by 2 characters from my PHP result.

HBHfHBCuHEHkKkCxL0OzXO vs JDJhJDEwJGJmMmEzN2Q1ZO

HBHfHBCuHEHkKkCxL0OzXO when shifted becomes JDJhJDEwJGJmMmEzN0QbZQ

PHP Salt decoded: $2a$10$bf2a37d5d
Your BCrypt Library salt decoded: $2a$10$bf2a37D�e

Any help would be greatly appreciated!

Additionally after testing, both hashes successfully verify using your library's verify() function.

Well, after a bit of work, I solved it. It seems as though you library's BCrypt encoder format's the salt using a Radix-64 encode while PHP's password_hash uses a standard base64 encode. I solved my problem by first encoding my salt with standard base64, then decoding it with your library's Radix-64 decoder. I then used the returned byte array as my salt byte array for your library's hash function. Example code here:
Radix64Encoder.Default re = new Radix64Encoder.Default();
byte[] enc = Base64.encode(salt.getBytes(), Base64.DEFAULT);
byte[] salt_byte = re.decode(enc);