如何将成员从其他系统导入Wordpress并更新密码以便他们能够正常工作?

时间:2015-07-30 21:40:40

标签: php wordpress

我们当前的系统(不使用Wordpress)有1000个用户需要移植到Wordpress。我们遇到的问题是密码不能保持不变。

在我们当前的系统中,密码保存为:

md5( md5( $password ) . USER_SALT ); // USER_SALT is a defined constant

显然不是最好的,但不是最差的......

我们需要制作这些我们目前在WP中工作的密码哈希值。有没有办法我们可以先通过此设置运行所有新密码,然后通过WP自己的散列运行?

我知道你可以加入像以下这样的功能:

function my_hash_password($password){
    return md5( md5( $password ) . USER_SALT );
}
add_action('wp_hash_password', 'my_hash_password' );

由于某种原因,它也没有完全发挥作用。

当然其他人已经经历过这个。

感谢。

编辑!!!!

到目前为止存在一些混乱。我不是要求不散列我们拥有的哈希密码。我所说的是,使用我们当前的系统,密码看起来像:

Password:  password
Hash function: md5( md5( $password ) . USER_SALT );
Output: d372f9c033e9c358b111ff265e080d3a

我想'也许'能够获取上面的哈希并将其提供给本机WP密码哈希,以便:

d372f9c033e9c358b111ff265e080d3a

...变为

$P$BdrwxndTzgTVHUozGpQ9TEMYd6mpTw0

经过他们的功能。

然后当用户登录时,我们通过我们的功能发回他们的纯文本密码,然后通过WP来获得匹配。

////////////////////////

更新!!!

///////////////////////

试图覆盖' wp_check_password' WP中可插入的功能,但由于某种原因,它似乎无法正常工作。

function my_check_password($password, $hash, $user_id = '') {
    global $wp_hasher;
    if ( $hash == md5( md5( $password ) . USER_SALT ) ){
        if ( $user_id ) {
        $check = true;
        wp_set_password($password, $user_id);
        $hash = wp_hash_password($password);
      }
      return apply_filters( 'check_password', $check, $password, $hash, $user_id );
    }

    // If the hash is still md5...
    elseif ( strlen($hash) <= 32 ) {
        $check = hash_equals( $hash, md5( $password ) );
        if ( $check && $user_id ) {
            // Rehash using new hash.
            wp_set_password($password, $user_id);
            $hash = wp_hash_password($password);
        }
        return apply_filters( 'check_password', $check, $password, $hash, $user_id );
    }

    // If the stored hash is longer than an MD5, presume the
    // new style phpass portable hash.
    if ( empty($wp_hasher) ) {
        require_once( ABSPATH . WPINC . '/class-phpass.php');
        // By default, use the portable hash from phpass
        $wp_hasher = new PasswordHash(8, true);
    }

    $check = $wp_hasher->CheckPassword($password, $hash);

    /** This filter is documented in wp-includes/pluggable.php */
    return apply_filters( 'check_password', $check, $password, $hash, $user_id );
}
add_action('wp_check_password', 'my_check_password' );

有人有什么想法吗?

4 个答案:

答案 0 :(得分:1)

这未经过测试,所以我不能肯定它会起作用,但假设USER_SALT是一个常数,就像你上面所示,你应该能够将它作为一个插件放在你的网站上,用户应该能够使用旧散列或默认的wordpress散列进行验证。别忘了调整OLD_SALT。

<?
/*
Plugin Name: Dual Password Checker
Plugin URI: http://tapy.com
Description: Checks passwords both with the wordpress hash and your old has
Version: 0.0.1
Author: tapy.com
Author URI: http://tapy.com
License: keep copyright in tact please
*/
require_once(ABSPATH . 'wp-includes/class-phpass.php');
class PasswordHashCustom extends PasswordHash{
    function CheckPassword($password, $stored_hash){
        return parent::CheckPassword($password, $stored_hash) ||
        md5(md5($password) . '56789') === $stored_hash;
    }
}
$wp_hasher = new PasswordHashCustom(8, TRUE);
?>

答案 1 :(得分:1)

我没有测试过这个,但是在wordpress目录中的inc / wp-phpass.php中

function crypt_private($password, $setting)
{
    $output = '*0';
    if (substr($setting, 0, 2) == $output)
        $output = '*1';

    $id = substr($setting, 0, 3);
    # We use "$P$", phpBB3 uses "$H$" for the same thing
    if ($id != '$P$' && $id != '$H$')
        return $output;

    $count_log2 = strpos($this->itoa64, $setting[3]);
    if ($count_log2 < 7 || $count_log2 > 30)
        return $output;

    $count = 1 << $count_log2;

    $salt = substr($setting, 4, 8);
    if (strlen($salt) != 8)
        return $output;

    # We're kind of forced to use MD5 here since it's the only
    # cryptographic primitive available in all versions of PHP
    # currently in use.  To implement our own low-level crypto
    # in PHP would result in much worse performance and
    # consequently in lower iteration counts and hashes that are
    # quicker to crack (by non-PHP code).
    if (PHP_VERSION >= '5') {
        $hash = md5($salt . $password, TRUE);
        do {
            $hash = md5($hash . $password, TRUE);
        } while (--$count);
    } else {
        $hash = pack('H*', md5($salt . $password));
        do {
            $hash = pack('H*', md5($hash . $password));
        } while (--$count);
    }

    $output = substr($setting, 0, 12);
    $output .= $this->encode64($hash, 16);

    return $output;
}

正如您所看到的,他们确实使用简单的md5作为密码,您可以将其更改为您自己的逻辑,请注意!每次WordPress更新此文件时都必须手动更改:/ 不是最好的解决方案,但我希望这可以帮助你

答案 2 :(得分:1)

实现此目的的最简单方法是创建一个插件。如果不创建具有该功能的插件,则无法完全覆盖WP功能。您可以完全覆盖的功能位于&quot; pluggable.php&#39;文件。哪个应该是自我解释,你需要创建一个&#39;插件&#39;覆盖它们。

我所要做的就是创建一个简单的插件:

  1. 向插件添加目录:/ plugins / my-password-updater
  2. 添加插件文件:

    /*
    Plugin Name: My Password Updater
    Plugin URI: Your Website
    Description: Checks both new and old passwords and updates old passwords
    Version: 0.0.1
    Author: Your Name
    Author URI: 
    License: 
    */
    
    if( ! function_exists( 'wp_check_password' ) ){
        function wp_check_password($password, $hash, $user_id = '') {
            global $wp_hasher;
    
            // Put whatever code from your old password hash check here
            // In my case it was the following...
            if ( $hash == md5( md5( $password ) . 'MY USER SALT' ) ){
                if ( $user_id ) {
                    $check = true;
                    wp_set_password($password, $user_id);
                    $hash = wp_hash_password($password);
                }
                return apply_filters( 'check_password', $check, $password, $hash, $user_id );
            }
    
            // The code below is from the original function
            elseif ( strlen($hash) <= 32 ) {
                $check = hash_equals( $hash, md5( $password ) );
                if ( $check && $user_id ) {
                    wp_set_password($password, $user_id);
                    $hash = wp_hash_password($password);
                }
                return apply_filters( 'check_password', $check, $password, $hash, $user_id );
            }
    
            if ( empty($wp_hasher) ) {
                require_once( ABSPATH . WPINC . '/class-phpass.php');
                $wp_hasher = new PasswordHash(8, true);
            }
            $check = $wp_hasher->CheckPassword($password, $hash);
            return apply_filters( 'check_password', $check, $password, $hash, $user_id );
        }
    }
    

答案 3 :(得分:0)

使用check_filter应该有效。这是我为导入PBKDF2 SHA256哈希编写的一个,采用Django使用的格式:

add_filter( 'check_password', function( $check, $password, $hash, $user_id ) {

    /* Just to be safe, since I'm not a security expert, I don't want the
     * Django hash fallback to work for administrators. They will need to
     * reset their password the normal way. */
    $user = get_userdata( $user_id );
    if ( empty( $user ) || in_array( 'administrator', $user->roles ) ) {
        return $check;
    }

    /*
     * Example Django hash for password "school bus":
     *
     * pbkdf2_sha256$100000$BbirbJq1C1G7$IcYmssO2bsILHcTCzLxPs/YmVGNmKb3cSt2JWzVzP2I=
     *
     */

    $rv = preg_match( '/^pbkdf2_sha256\$([0-9]+)\$(.+)\$(.+)$/', $hash, $matches );
    if ($rv === 1) {
        $iterations = intval( $matches[1] );
        $salt = $matches[2];
        $expected_base64_hash = $matches[3];

        $got_base64_hash = base64_encode( hash_pbkdf2( "sha256", $password, $salt, $iterations, 0, true ) );

        if ( $expected_base64_hash === $got_base64_hash ) {
            /* Save the password in WordPress default format, so that we
             * can turn this plugin off some day. */
            wp_set_password( $password, $user_id );

            return true;
        } else {
            return false;
        }
    } elseif ( $rv === 0 ) {
        return $check;
    } else {
        error_log( "An error occurred with the regex in " . __FUNCTION__ . " " . __FILE__ );
        return $check;
    }
}, 10, 4 );