Forums

Home » Liferay Portal » English » 3. Development

Combination View Flat View Tree View
Threads [ Previous | Next ]
toggle
Gabrijel G
Replicate PBKDF2PasswordEncryptor in PHP
May 10, 2017 3:27 PM
Answer

Gabrijel G

Rank: New Member

Posts: 1

Join Date: May 10, 2017

Recent Posts

For a project we need to be able to mimic the password generation in a PHP app so we can validate the password hash directly against the DB without going through Liferay.
My Java knowledge and my Liferay knowledge isn't as splendid as I'd like it to be... any help would be greatly apreciated!

The Liferay version that's active is v 6.2 and the used password/hash method is PBKDF2PasswordEncryptor, keysize: 160, rounds: 128000.

If managed to extract the keysize and the rounds form the hash:
1$rawEncrypted = base64_decode($encrypted);
2// keysize is found in the first 4 bytes
3$keySize = unpack('N', substr($raw, 0, 4));
4$keySize = end($keySize); // result: 160
5// rounds is found in the next 4 bytes
6$rounds  = unpack('N', substr($raw, 4, 4)); // result: 128000
7$rounds  = end($rounds);


Now, when I'm trying to get the salt (next 8 bytes) I'm not quote sure if I'm getting the right salt, two examples:
1$salt = unpack('N', substr($raw, 8, 8)); // returns a large integer, e.g. 4006721064

1$salt = unpack('H*', substr($raw, 8, 8)); // return a string/hex, e.g. eedf4e8ed639571a


Now, the next part gets me quite confused. There are only 36 chars stored in the DB for the password hash. So that leaves (36-4-4-8=) 20 bytes/chars left for the password hash (from plain text).
Am I missing something? I thought I'd have to use the PHP function "hash_pbkdf2" (with the exact same specs: sha1, plain pass, found salt, rounds, keysize) and I end up with a large hash/string. So now:
  • Am I generating the pass correctly (do I need to do something with the salt?)
  • How am I supposed to create the final hash (36 chars) with the keysize, rounds and salt embedded?


Thank you very much,
GG.
David H Nebinger
RE: Replicate PBKDF2PasswordEncryptor in PHP
May 10, 2017 3:34 PM
Answer

David H Nebinger

Community Moderator

Rank: Liferay Legend

Posts: 13401

Join Date: September 1, 2006

Recent Posts

Seems like an awful PITA if you ask me.

Why not just invoke an authenticated web service call against Liferay w/ the credentials in a BasicAuth header and evaluate the response code from the server (200 vs 40x codes)?








Come meet me at the 2017 LSNA!
Tomas Polesovsky
RE: Replicate PBKDF2PasswordEncryptor in PHP
August 18, 2017 7:51 AM
Answer

Tomas Polesovsky

LIFERAY STAFF

Rank: Liferay Master

Posts: 653

Join Date: February 13, 2009

Recent Posts

For any future readers

PBKDF2PasswordEncryptor.java#L79-L87

So the password is saved as [key size in 4 bytes] [rounds in 4 bytes] [salt in 8 bytes] [secret key, length based on key size]

Example
1MariaDB [lportal_trunk]> select password_ from User_ where emailAddress = 'test@liferay.com';
2+--------------------------------------------------+
3| password_                                        |
4+--------------------------------------------------+
5| AAAAoAAB9AC8xZlFnkixAsLnhJKYm56jV4o/6fpg84YfmlFE |
6+--------------------------------------------------+


Translated into hex:

1echo -n 'AAAAoAAB9AC8xZlFnkixAsLnhJKYm56jV4o/6fpg84YfmlFE' | base64 -d - | xxd
20000000: 0000 00a0 0001 f400 bcc5 9945 9e48 b102  ...........E.H..
30000010: c2e7 8492 989b 9ea3 578a 3fe9 fa60 f386  ........W.?..`..
40000020: 1f9a 5144                                ..QD


So applied: [0000 00a0] [0001 f400] [bcc5 9945 9e48 b102] [c2e7 8492 989b 9ea3 578a 3fe9 fa60 f386 1f9a 5144]

1int keySize = 0x0000 00a0 = 160 (20 bytes)
2int rounds = 0x000 1f400 = 128000
3byte[] salt = [0xbc, 0xc5, 0x99, 0x45, 0x9e, 0x48, 0xb1, 0x02]
4byte[] pbkdf2Hash = [0xc2, 0xe7, 0x84, 0x92, 0x98, 0x9b, 0x9e, 0xa3, 0x57, 0x8a, 0x3f, 0xe9, 0xfa, 0x60, 0xf3, 0x86, 0x1f, 0x9a, 0x51, 0x44]


Testing with PHP:
 1(cat <<"EOF"
 2<?php
 3$keySize = 20;
 4$rounds = 128000;
 5$salt = implode(array_map("chr",[0xbc, 0xc5, 0x99, 0x45, 0x9e, 0x48, 0xb1, 0x02]));
 6$expected = bin2hex(implode(array_map("chr",[0xc2, 0xe7, 0x84, 0x92, 0x98, 0x9b, 0x9e, 0xa3, 0x57, 0x8a, 0x3f, 0xe9, 0xfa, 0x60, 0xf3, 0x86, 0x1f, 0x9a, 0x51, 0x44])));
 7
 8$password = "test";
 9$hash = bin2hex(hash_pbkdf2("sha1", $password, $salt, $rounds, $keySize, true));
10
11echo "
12Expected: $expected
13Actual:   $hash";
14
15EOF
16) | php

1Expected: c2e78492989b9ea3578a3fe9fa60f3861f9a5144
2Actual:   c2e78492989b9ea3578a3fe9fa60f3861f9a5144

Participate in the State of Liferay Community 2017. Help the community and even win some prizes!