[HowTO] Import passwords from another forum (phpbb3)



  • My be usefull for someone.

    I have old phphbb3 forum and import all users/posts with nodebb-plugin-import-phpbb. But this plugin didn't impost passwords, because database keep only hashes. You need generate new passwords and this very painful for your forum users. This is my solution to keep users passwords:

    Step 1. Copy old hashes from mysql to mongodb

    After import users and before clear temp date I copy pass hashes from old forum to mongodb. This is my python script (i newbie in JS, python my choice). I have 2900 users, so you need change this number (and also change database, user/password and prefix for mysql connection). Also my mongodb without password, you need adapt this script if you use mongodb password.

    #!/bin/python3
    
    from pymongo import MongoClient
    import os
    import mysql.connector
    
    
    client = MongoClient()
    db = client["nodebb2"]
    coll = db["objects"]
    
    cnx = mysql.connector.connect(user='phpbb_user_db', password='your_password',host='127.0.0.1',database='forum')
    cursor = cnx.cursor()
    
    for new_uid in range(1,2900):
        user = coll.find_one({"_key":"user:" + str(new_uid)})
        if user:
            old_uid = user["_imported_uid"]
            
            query = ("SELECT user_password FROM `phpbb3_users` WHERE `user_id`= %d"%old_uid)
            cursor.execute(query)
        
            for (_user_password,) in cursor:
                user_password = '$P$' + _user_password.decode('utf-8')[3:]
                new_pass = {}
                new_pass["passwordExpiry"] = 0
                new_pass["password"] = user_password
                db["objects"].update({'_id':user["_id"]}, {"$set": new_pass})
    
                print("update_user %d"%old_uid)
    

    Step 2. Install lib for phpass hash

    npm install wordpress-hash-node
    

    Step 3. Change password check procedure

    But phpbb3 use phpass hash, nodebb use bcrypt. To solve this I change file bcrypt.js. My bcrypt.js file:

    'use strict';
    
    var bcrypt = require('bcryptjs'),
            hashPhpbb3 = require('wordpress-hash-node'),
            winston = require('winston'),
    	async = require('async');
    
    
    process.on('message', function(msg) {
    	if (msg.type === 'hash') {
    		hashPassword(msg.password, msg.rounds);
    	} else if (msg.type === 'compare') {
                    if (msg.hash.length === 34 && msg.hash.substring(0,3) === '$P$') {
                            if (hashPhpbb3.CheckPassword(msg.password, msg.hash)){
                                    done(null, true);
                            }
                            else{
                                    done(null, false);
                            }
                    }
                    else{
    		        bcrypt.compare(msg.password, msg.hash, done);
                    }
    	}
    });
    
    function hashPassword(password, rounds) {
    	async.waterfall([
    		function(next) {
    			bcrypt.genSalt(parseInt(rounds, 10), next);
    		},
    		function(salt, next) {
    			bcrypt.hash(password, salt, next);
    		}
    	], done);
    }
    
    function done(err, result) {
    	if (err) {
    		process.send({err: err.message});
    		return process.disconnect();
    	}
    	process.send({result: result});
    	process.disconnect();
    }
    

    Original bcrypt.js:

    'use strict';
    
    var bcrypt = require('bcryptjs'),
    	async = require('async');
    
    
    process.on('message', function(msg) {
    	if (msg.type === 'hash') {
    		hashPassword(msg.password, msg.rounds);
    	} else if (msg.type === 'compare') {
    		bcrypt.compare(msg.password, msg.hash, done);
    	}
    });
    
    function hashPassword(password, rounds) {
    	async.waterfall([
    		function(next) {
    			bcrypt.genSalt(parseInt(rounds, 10), next);
    		},
    		function(salt, next) {
    			bcrypt.hash(password, salt, next);
    		}
    	], done);
    }
    
    function done(err, result) {
    	if (err) {
    		process.send({err: err.message});
    		return process.disconnect();
    	}
    	process.send({result: result});
    	process.disconnect();
    }
    

    Step 4. Restart nodebb


  • Global Moderator

    It's a bad idea to copy password hashes from one site to another or to introduce alternative security verification measures if you don't know what you're doing. I'd recommend just forcing users to reset their password when you switch from your old site to your new site as it's the most secure way.



  • @PitaJ it's not "one site to another". Its from my old forum to new forum.

    introduce alternative security verification measures if you don't know what you're doing

    Why? I use library, not my own code. If user change password, it will be hashed by bcrypt mythod. And my alternative "if" case never be executed for him.

    I realize that my method less secure than generate new password, but just little bit, not critical. I not double check passwords with 2 different methods, I check with phpbb3 method only when hash in db looks like phpass hash. It also secure, use salt etc (phpbb3 and wordpress use this method).

    Change forum and also all password same time very stressful for users, in my opinion. It's just solution for me, use it at own risk.


  • Community Rep

    I think this is fine, as long as you didn't transfer / save the hashes somewhere else in plaintext. Some of the disadvantages to rolling your own password hash check here is that it looks like you're not using the multiple bcrypt rounds, which may make you more susceptible to brute force attacks.


  • Admin

    Very cool, thanks for sharing 😄



  • It's just what I needed. Thanks


Log in to reply
 


Star

Looks like your connection to NodeBB was lost, please wait while we try to reconnect.