如何使用PHP在数据库中验证WordPress生成的密码?

时间:2011-10-24 作者:SharkTheDark

我正在使用WordPress完成的站点,我需要添加一些WP之外的部分,并检查用户登录,记录WP之外的用户。

我试过用md5的密码,但它不是。。。

我尝试了以下代码:

require_once( \'wp-includes/class-phpass.php\' );
$wp_hasher = new PasswordHash( 8, TRUE );
$password = "passwordhere";
$hashed_password = $wp_hasher->HashPassword( $password );
$encryptedpass = md5($hashed_password);
但这只是第一次创建密码,而且总是不同的。

我需要可以在以下方面使用的代码:

SELECT * FROM wp_customers WHERE email = "[email protected]" AND password = "<what goes here?>"
这有可能吗?

谢谢

4 个回复
最合适的回答,由SO网友:EAMann 整理而成

根据你的另一个问题。。。听起来像是在根据数据库中存储的内容验证给定的明文密码。WordPress使用以下函数来实现这一点:

function wp_check_password($password, $hash, $user_id = \'\') {
    global $wp_hasher;

    // If the hash is still md5...
    if ( strlen($hash) <= 32 ) {
        $check = ( $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 . \'wp-includes/class-phpass.php\');
        // By default, use the portable hash from phpass
        $wp_hasher = new PasswordHash(8, TRUE);
    }

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

    return apply_filters(\'check_password\', $check, $password, $hash, $user_id);
}
首先,该插件检查给定密码的MD5哈希是否与用户存储的(哈希)密码相同。它还检查给定密码的PHPass哈希是否与用户存储的密码相同。

您可以遵循类似的模式。

假设用户给了你一个用户名和密码,你想验证它们(my_password_validation( $username, $password )). 您将使用给定的用户名从数据库中提取哈希密码。然后将给定密码的哈希值与存储的值进行比较,以查看其是否有效。

这里有一些untested psuedocode

function my_password_validation( $username, $password ) {
    // Select the users\'s password hash from the database
    $stored = query( \'SELECT * FROM wp_customers WHERE email = \' . $username );

    require_one( \'class-phpass.php\' );
    $hasher = new PasswordHash(8, TRUE);

    return $hasher->CheckPassword( $password, $stored );
}
如果传递给函数的密码哈希值与存储的值相同,则函数将返回true。否则将返回false。

查看comments 你在另一个问题上离开了,但似乎你还有其他问题。引用:

所以我得到:

$P$BqVYujC/jqNY4aylZpHi475jwcaSUs1但我如何将其与DB中的一个进行比较?

DB中的一个为:

fa063a4ed35e092a2d4e15c1b6a61871如何将两者与MySQL进行比较?

我现在可以告诉您,您从数据库中获取的密码没有使用PHPass实用程序进行散列。这些哈希值将始终类似于$P$B 开始是因为这告诉系统它是如何散列的。PHPass基于Blowfish,它在加密字符串上使用这种前缀。

你的fa063... 哈希看起来更像标准的MD5哈希。。。因此,如果您的MD5明文哈希不匹配,那么我认为您可能有错误的密码。

回答您的“问题”;如何将这两者与MySQL进行比较;问题你没有。MySQL是数据存储。。。不要在数据存储中执行任何业务逻辑或比较。读取数据,然后使用PHP脚本执行比较。

SO网友:BagusS

It\'s very easy..

<?php
include_once($_SERVER[\'DOCUMENT_ROOT\'].\'/wp-includes/class-phpass.php\' );

// prepare database connection
$ip_address="localhost";
$user_db="userdb";
$pass_db="passdb";

$conn= mysql_connect($ip_address,$user_db,$pass_db);
mysql_select_db("dbname",$conn);
if (!$conn){
            echo "Could not connect: " . mysql_error();
            exit();
}

// wordpress\' username that his password going to compare
$user = \'test\';
$user_name = htmlspecialchars($user,ENT_QUOTES);

// plain password to compare
$password = \'tespass\';

$hasher = new PasswordHash(8, TRUE);

// get user_name\'s hashed password from wordpress database
$queryx = "select * from wa1gty5f_users where user_login=\'$user_name\'";
$Resultx = mysql_query($queryx,$conn);

while($row = mysql_fetch_array($Resultx)){
     $passnya = $row[user_pass];
}

// compare plain password with hashed password
if ($hasher->CheckPassword( $password, $passnya )){
    echo "MATCHED";
} else {
    echo "NO MATCHED";
}
?>
SO网友:Alex

我遇到了这个问题,并在wp_hash_password()

将已哈希的密码与其纯文本字符串进行比较

<?php

$wp_hasher = new PasswordHash(8, TRUE);

$password_hashed = \'$P$B55D6LjfHDkINU5wF.v2BuuzO0/XPk/\';
$plain_password = \'test\';

if($wp_hasher->CheckPassword($plain_password, $password_hashed)) {
    echo "YES, Matched";
} else {
    echo "No, Wrong Password";
}

?>

SO网友:Md. Hasan Mahmud

最后,大约10年后。找到了确切的答案,问题是什么。

您想使用核心PHP来实现这一点,对吗?这是你的密码!首先,您需要添加一个类:->;只需从wp-includes/class-phpass.php-&燃气轮机;别担心。它是用核心PHP编写的。

class PasswordHash {
    var $itoa64;
    var $iteration_count_log2;
    var $portable_hashes;
    var $random_state;

    /**
     * PHP5 constructor.
     */
    function __construct( $iteration_count_log2, $portable_hashes )
    {
        $this->itoa64 = \'./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\';

        if ($iteration_count_log2 < 4 || $iteration_count_log2 > 31)
            $iteration_count_log2 = 8;
        $this->iteration_count_log2 = $iteration_count_log2;

        $this->portable_hashes = $portable_hashes;

        $this->random_state = microtime() . uniqid(rand(), TRUE); // removed getmypid() for compatibility reasons
    }

    /**
     * PHP4 constructor.
     */
    public function PasswordHash( $iteration_count_log2, $portable_hashes ) {
        self::__construct( $iteration_count_log2, $portable_hashes );
    }

    function get_random_bytes($count)
    {
        $output = \'\';
        if ( @is_readable(\'/dev/urandom\') &&
            ($fh = @fopen(\'/dev/urandom\', \'rb\'))) {
            $output = fread($fh, $count);
            fclose($fh);
        }

        if (strlen($output) < $count) {
            $output = \'\';
            for ($i = 0; $i < $count; $i += 16) {
                $this->random_state =
                    md5(microtime() . $this->random_state);
                $output .=
                    pack(\'H*\', md5($this->random_state));
            }
            $output = substr($output, 0, $count);
        }

        return $output;
    }

    function encode64($input, $count)
    {
        $output = \'\';
        $i = 0;
        do {
            $value = ord($input[$i++]);
            $output .= $this->itoa64[$value & 0x3f];
            if ($i < $count)
                $value |= ord($input[$i]) << 8;
            $output .= $this->itoa64[($value >> 6) & 0x3f];
            if ($i++ >= $count)
                break;
            if ($i < $count)
                $value |= ord($input[$i]) << 16;
            $output .= $this->itoa64[($value >> 12) & 0x3f];
            if ($i++ >= $count)
                break;
            $output .= $this->itoa64[($value >> 18) & 0x3f];
        } while ($i < $count);

        return $output;
    }

    function gensalt_private($input)
    {
        $output = \'$P$\';
        $output .= $this->itoa64[min($this->iteration_count_log2 +
            ((PHP_VERSION >= \'5\') ? 5 : 3), 30)];
        $output .= $this->encode64($input, 6);

        return $output;
    }

    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;
    }

    function gensalt_extended($input)
    {
        $count_log2 = min($this->iteration_count_log2 + 8, 24);
        # This should be odd to not reveal weak DES keys, and the
        # maximum valid value is (2**24 - 1) which is odd anyway.
        $count = (1 << $count_log2) - 1;

        $output = \'_\';
        $output .= $this->itoa64[$count & 0x3f];
        $output .= $this->itoa64[($count >> 6) & 0x3f];
        $output .= $this->itoa64[($count >> 12) & 0x3f];
        $output .= $this->itoa64[($count >> 18) & 0x3f];

        $output .= $this->encode64($input, 3);

        return $output;
    }

    function gensalt_blowfish($input)
    {
        # This one needs to use a different order of characters and a
        # different encoding scheme from the one in encode64() above.
        # We care because the last character in our encoded string will
        # only represent 2 bits.  While two known implementations of
        # bcrypt will happily accept and correct a salt string which
        # has the 4 unused bits set to non-zero, we do not want to take
        # chances and we also do not want to waste an additional byte
        # of entropy.
        $itoa64 = \'./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\';

        $output = \'$2a$\';
        $output .= chr(ord(\'0\') + $this->iteration_count_log2 / 10);
        $output .= chr(ord(\'0\') + $this->iteration_count_log2 % 10);
        $output .= \'$\';

        $i = 0;
        do {
            $c1 = ord($input[$i++]);
            $output .= $itoa64[$c1 >> 2];
            $c1 = ($c1 & 0x03) << 4;
            if ($i >= 16) {
                $output .= $itoa64[$c1];
                break;
            }

            $c2 = ord($input[$i++]);
            $c1 |= $c2 >> 4;
            $output .= $itoa64[$c1];
            $c1 = ($c2 & 0x0f) << 2;

            $c2 = ord($input[$i++]);
            $c1 |= $c2 >> 6;
            $output .= $itoa64[$c1];
            $output .= $itoa64[$c2 & 0x3f];
        } while (1);

        return $output;
    }

    function HashPassword($password)
    {
        if ( strlen( $password ) > 4096 ) {
            return \'*\';
        }

        $random = \'\';

        if (CRYPT_BLOWFISH == 1 && !$this->portable_hashes) {
            $random = $this->get_random_bytes(16);
            $hash =
                crypt($password, $this->gensalt_blowfish($random));
            if (strlen($hash) == 60)
                return $hash;
        }

        if (CRYPT_EXT_DES == 1 && !$this->portable_hashes) {
            if (strlen($random) < 3)
                $random = $this->get_random_bytes(3);
            $hash =
                crypt($password, $this->gensalt_extended($random));
            if (strlen($hash) == 20)
                return $hash;
        }

        if (strlen($random) < 6)
            $random = $this->get_random_bytes(6);
        $hash =
            $this->crypt_private($password,
            $this->gensalt_private($random));
        if (strlen($hash) == 34)
            return $hash;

        # Returning \'*\' on error is safe here, but would _not_ be safe
        # in a crypt(3)-like function used _both_ for generating new
        # hashes and for validating passwords against existing hashes.
        return \'*\';
    }

    function CheckPassword($password, $stored_hash)
    {
        if ( strlen( $password ) > 4096 ) {
            return false;
        }

        $hash = $this->crypt_private($password, $stored_hash);
        if ($hash[0] == \'*\')
            $hash = crypt($password, $stored_hash);

        return $hash === $stored_hash;
    }
}
你差不多完成了。

$password = \'binary1001\';//password you want to verify

$hasher = new PasswordHash(8, TRUE);
$passnya = \'$P$BFG8I1k171qgRKqZvj0K3tn3bBSrsW/\';//hash of that password from wp db


// compare plain password with hashed password
if ($hasher->CheckPassword( $password, $passnya )){
    echo "MATCHED";
} else {
    echo "NO MATCHED";
}
我在这里反复尝试。现在,是你切入正题的时候了。快乐的编码!!!

结束

相关推荐

您可以从变量回显PHP代码吗?

好吧,这是一个愚蠢的问题,我甚至不确定我问得对不对,但这就是我想做的。我的wordpress主题支持广告投放,我想使用广告管理器插件。我知道我可以浏览主题,用插件中的代码替换当前存在的广告代码。然而,该主题在帖子之间的广告位置等方面做了一些其他的事情(我不确定要保留哪些内容)。所以我希望有一个更简单的解决方案。如果我将插件中的php代码放入主题中的广告放置框中,它所做的就是在页面源代码中这样做(基本上是对其进行注释)。<!--?php if( function_exists( \'pro_ad_di