I want to authenticate WP users using my own authentication service written in Node. I have users saved in the wp_users
table. Their passwords are hashed using Phpass method by WordPress. When a user is trying to log into his account, WP is using CheckPassword()
method and returns boolean true
/false
if the password matches or not.
Now I want to use Node to compare user password to the WP hash. I found node-phpass module on NPM, which is supposed to provide the Phpass algorithm for password hashing.
It's all fine until I use international characters. Here's an example:
In WP, I set the password like this, and get a hash:
P: alamakota
H: $P$BSrncAWIY2KU7waUGLzayaon6v3gKU1
When I try to log in, WP says "All fine, come in, man"
Now, I take the hash and try to validate it using node-phpass module:
const hasher = new PasswordHash(8, true, 7);
const valid = hasher.CheckPassword('alamakota', '$P$BSrncAWIY2KU7waUGLzayaon6v3gKU1');
console.log(valid); // => true
and it says "Cool, password match!"
It works perfectly in the other way also.
Now, where does the problem occur, you may ask? Here:
The situation is almost exactly the same as before, but I will put ą
character in the password and hash it using WP:
P: alamakotą
H: $P$B6kY.rneyNwdPvAgd0lDq6oYv82XOd1
Again, when validated using WP, it says "Password match! Come in."
Unfortunately, when I try to compare the password using node-phpass, it says "Sorry, man, you shall not pass":
const hasher = new PasswordHash(8, true, 7);
const valid = hasher.CheckPassword('alamakotą', '$P$B6kY.rneyNwdPvAgd0lDq6oYv82XOd1');
console.log(valid); // => false
It also doesn't work in the other way.
Why is it so? Why can I not use WP hash in the Node.js when there are international characters in the password?
UPDATE:
I've just found that PHP's md5()
function and JS'es crypto.createHash('md5')
does not return the same hash when there are international characters in the input string. Is there any solution for that?
So it turned out that the PHP's md5()
function returns different hash than JS'es crypto.createHash('md5')
because of character encoding. I've used utf8 before comparing the password against the hash and everything works as expected:
const utf8 = require('utf8');
const hasher = new PasswordHash(8, true, 7);
const valid = hasher.CheckPassword(utf8.encode('alamakotą'), '$P$B6kY.rneyNwdPvAgd0lDq6oYv82XOd1');
console.log(valid); // => true