0

Basically, I want to mirgrate a list of users with a pw that is hashed with pbkdf2-sha256 to a cms which uses phpass.

In order to accomplish this I try to check the entered pw by the user and generate the typo3 hashed pw in order to compare it with the record in the database.


I tried to reverse engineer the pbkdf2 hashing that typo3 uses (with a example user pw), but I don't get the expected result:

base64_encode( hash_pbkdf2( "sha256", "88t8R7EfRj9Xf3P", "4f3YKAmnn1dBBU1OPwfdzQ", 25000, 0, true ));

Result: x806WJJRfoHq25Pq2OTs3xfa18qIJ7tzwWaAzO3aKzU=

The stored hashed pw in the db is:

$pbkdf2-sha256$25000$4f3YKAmnn1dBBU1OPwfdzQ$fq4u5vEp6hm8G6Xi7E2UcnEjcLRgMhJ2Yx9v7ikWyZs


When I try this with a given example from stack overflow it works:

 base64_encode( hash_pbkdf2( "sha256", "school bus", "BbirbJq1C1G7", 100000, 0, true ));

Result: IcYmssO2bsILHcTCzLxPs/YmVGNmKb3cSt2JWzVzP2I=

expected result: pbkdf2_sha256$100000$BbirbJq1C1G7$IcYmssO2bsILHcTCzLxPs/YmVGNmKb3cSt2JWzVzP2I=

I would really appreciate if someone can help with this.

Greetings, Julian

Julian
  • 1
  • 2
  • Just to clearify. On wordpress the user enters his credentials, and you want to check if is correct against the old value what was used on a typo3 instance ? So to say ... migrating from typo3 to wordpress ? The other question which is not clear, instead of the direction, do you mean backend or frontend users ? if i'm correct that you migrating away from typo3, please note the typo3 version, be or frontenduser and which fe login system was used. If the direction is wordpress to typo3 i think frontend or backend use would be a nice info, too. (also i', not familiar with wordpress) – Stefan Bürk Jul 19 '21 at 20:50
  • If in the first code snippet in `hash_pbkdf2()` the salt (i.e. the 3rd parameter) is Base64 decoded: `base64_decode("4f3...dzQ")`, the desired result `fq4... yZs` is obtained except the Base64 padding (which is optional). – Topaco Jul 20 '21 at 06:28
  • Thanks a lot! base64_decode the salt before using it in hash_pbkdf2() brings the desired result! – Julian Jul 20 '21 at 12:32
  • How can I achieve the padding, because if I set the length in hash_pbkdf2() it wount bring the expected result because of being base64encoded afterwards. Should I just cut away the last char to get the needed length? I only have one example user in the database set so I can't test if this works for every pw... – Julian Jul 20 '21 at 12:43
  • The base64 padding is optional, but can be derived from the length of the base64 encoded data if it is to be added. Reversely, simply remove the padding bytes at the end, for details see https://en.wikipedia.org/wiki/Base64#Output_padding. – Topaco Jul 21 '21 at 06:41

2 Answers2

0

You found the answer on your own if you have a closer look at your last example.

You wrote you tried this:

base64_encode( hash_pbkdf2( "sha256", "88t8R7EfRj9Xf3P", "4f3YKAmnn1dBBU1OPwfdzQ", 25000, 0, true ));

and hash is incorrect but this one is "partially" what you expect:

base64_encode( hash_pbkdf2( "sha256", "school bus", "BbirbJq1C1G7", 100000, 0, true ));

The key difference here is using 100000 vs 25000. You have to provide the same parameters as TYPO3 does (firstly).

Secondly, the hash generated by TYPO3 and stored in database is what you get from that method call AND is prefixed by some additional information about the hash. In your last example, this:

pbkdf2_sha256$100000$BbirbJq1C1G7$IcYmssO2bsILHcTCzLxPs/YmVGNmKb3cSt2JWzVzP2I=

Thus this shows:

  1. The hash algorithm in use (pbkdf2_sha256)
  2. a separator ($)
  3. Number of run (100000)
  4. a separator ($)
  5. The salt being used by the hash algorithm (BbirbJq1C1G7)
  6. a separator ($)
  7. The hash itself (IcYms...)

Just concatenate everything together and you'll get a compatible hash for TYPO3. Explode at the separators ($) and you'll get the various parts.

Now, it is naturally obvious but just to be complete... you won't be able to "convert" or "migrate" the hashes from one algorithm to another one, because this would defeat the whole security. A hash is not an encrypted cipher, it's a 1-way operation. So the only way to "migrate" from pbkdf2_sha256 to phppass for your Wordpress install will be to get the real password from your users (logically for you this means during the authentication process in TYPO3) and hash it using the new algorithm you need, thus either migrating over time all of your TYPO3 user passwords to the new algorithm or storing both representations "somewhere".

Xavier
  • 31
  • 2
  • Thanks a lot for your answer. I know that the whole stored pw is a chain of all the params and the hash at least, but there was a problem with the generated hash, but the answer from user9014097 helped, decoding the salt before using it leads to the correct hash. Regarding the problem of the 1-way oparation, I don't try to get the passwords, I just compare the user pw input with the one in the database and if it fits I use the entered pw and hash it with the new (phpass) method and overwrite the value in the database in order to get rid of the old hashed passwords in future! – Julian Jul 20 '21 at 12:37
0

This does the trick except the padding:

$salt = base64_decode("4f3YKAmnn1dBBU1OPwfdzQ");
$hash_to_compare_with_db = base64_encode( hash_pbkdf2( "sha256", "88t8R7EfRj9Xf3P", $salt, 25000, 0, true ));

Thanks to all and especially to user 9014097

Julian
  • 1
  • 2