I'm using phpbb 3.0.8 at the moment. It has 3,000 users and around 60,000 posts. I'm changing the forum to a different one, written in classic ASP (I know people are going to disapprove of this but I have good reasons).
My site is written in ASP.net. The classic ASP forum has an API to connect to it. I've set all this up, and it works fine. I have written my own login form.
I want to copy all the user accounts over. The current forum has the table:
Username | Password | Hash | Salt
I've overidden the classic ASP hashing technique to now use the ASP.net Security.SHA1
hash. The password is stored as SHA1(rawpassword + salt)
.
My plan is to store new fields along side the current ones:
UserID | Password | Hash | Salt | PHPBBHash
When the user logs in, if the PHPBB hashh field is set, it hashes the password with the PHPBB hash. Then, if login is sucessful, it deletes the PHPBBHash field, and creates the current systems hash values. This way, it's a smooth transition over from PHPBB to the new forum, and no one loses their accounts.
My problem is, given a PHPBB hash, a username, and password, in ASP.net c# how can I verify the PHPBB hash? How does it calculate it?
My concern is also that the classic ASP hash function claimed to be SHA1, but it produced different results to Securiy.SHA1
.
Edit
I've put a bounty on this if anyone can give me a definitive solution, I appreciate the answer linking to the resources but I'm still struggling to understand it.
Test Case
Raw password:
blingblangblaow222
In PHPBB3 database:
username: Tom
username_clean: tom
user_password: $H$9ojo08A3LuhnkXR27p.WK7dJmOdazh0
user_passchg: 1301433947
user_form_salt: 637f480dfdab84ef
Using the example code from Vishalgiris answer, we do this:
phpBB.phpBBCryptoServiceProvider cPhpBB = new phpBB.phpBBCryptoServiceProvider();
string remoteHash = "$H$9ojo08A3LuhnkXR27p.WK7dJmOdazh0";
bool result = cPhpBB.phpbbCheckHash("blingblangblaow222", remoteHash);
Response.Write("<BR><BR><BR>" + result);
This actually returns true. Super! But does anyone know why this works? I'm baffled, it doesn't seem to take salt into account at all.
user_form_salt
into account. In actuality, the 8 characters after the first 4 characters are the salt used in the hash (based on the source code I linked to). It roughly goes like this: 3-character magic string ($H$
), 1 character representing the exponent of the number of times to hash (base 2,9
- 2^9), an 8-character salt, followed by a 16-character hash. – Congratulate