针对PHP中的SSHA256哈希验证密码 [英] Validate a password against an SSHA256 hash in PHP

查看:336
本文介绍了针对PHP中的SSHA256哈希验证密码的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于使用Dovecot进行身份验证,我使用SSHA256哈希,但是我不知道如何针对现有哈希来验证给定密码.以下PHP函数(可在Web上找到它们)用于创建SSHA256哈希:

For authentification with Dovecot, I use SSHA256 hashes but I have no clue how to validate a given password against the existing hash. The following PHP functions (found them in the web) are used to create the SSHA256 hash:

function ssha256($pw) {
        $salt = make_salt();
        return "{SSHA256}" . base64_encode( hash('sha256', $pw . $salt, true ) . $salt );
}

function make_salt() {
        $len   = 4;
        $bytes = array();
        for ($i = 0; $i < $len; $i++ ) {
                $bytes[] = rand(1,255);
        }
        $salt_str = '';
        foreach ($bytes as $b) {
                $salt_str .= pack('C', $b);
        }
        return $salt_str;
}

示例输出:{SSHA256}lGq49JTKmBC49AUrk7wLyQVmeZ7cGl/V13A9QbY4RVKchckL

我必须提取盐,但是如何提取? 我完全迷失了解决问题的方式,对此有人有暗示吗?

Do I have to extract the salt, but how? I totally lost the way for solving the problem, has anyone a hint for this?

感谢大家的帮助!

哦,很抱歉,我必须使用SSHA256,因为Dovecot 1.2.15仅支持以下方案: CRYPT MD5 MD5-CRYPT SHA SHA1 SHA256 SMD5 SSHA SSHA256 PLAIN CLEARTEXT CRAM-MD5 HMAC-MD5 DIGEST-MD5 PLAIN-MD4 PLAIN-MD5 LDAP-MD5 LANMAN NTLM OTP SKEY RPA

Oh and sorry, I have to use SSHA256, because Dovecot 1.2.15 supports only those schemes: CRYPT MD5 MD5-CRYPT SHA SHA1 SHA256 SMD5 SSHA SSHA256 PLAIN CLEARTEXT CRAM-MD5 HMAC-MD5 DIGEST-MD5 PLAIN-MD4 PLAIN-MD5 LDAP-MD5 LANMAN NTLM OTP SKEY RPA

推荐答案

您不应将SHA系列用于密码哈希.它们快速,并且设计用于快速哈希文件.您需要使用pashword散列来 昂贵 .使用bcrypt,PHPass或只使用我自己滚动的此类(但要等到您学会在其中学习漏洞时再使用):

You should not be using the SHA family for password hashing. They are fast and designed for hashing files at speed. You need pashword hashing to be expensive. Use bcrypt, PHPass or just use this class, which I rolled myself (but not until you learn to pick holes in it):

class PassHash {
    public static function rand_str($length) {
        $total = $length % 2;
        $output = "";
        if ($total !== 0) {
            $count = floor($length / 2);
            $output .= ".";
        } else $count = $length / 2;

        $bytes = openssl_random_pseudo_bytes($count);
        $output .= bin2hex($bytes);

        // warning: prepending with a dot if the length is odd.
        // this can be very dangerous. no clue why you'd want your
        // bcrypt salt to do this, but /shrug

        return $output;
    }
    // 2y is an exploit fix, and an improvement over 2a. Only available in 5.4.0+
    public static function hash($input) {
        return crypt($input, "$2y$13$" . self::rand_str(22));

    }

    // legacy support, add exception handling and fall back to <= 5.3.0
    public static function hash_weak($input) {
        return crypt($input, "$2a$13$" . self::rand_str(22));
    }

    public static function compare($input, $hash) {
        return (crypt($input, $hash) === $hash);
    }
}

您必须对给定的纯文本进行哈希处理,然后将该哈希与已存储的哈希进行比较.盐存储在散列中,并且应该是随机的.如果愿意,可以加入胡椒粉.您还应该使workrate变量可变,以便您可以在需要时随时更改工作率,并且仍然可以使系统正常工作.

You have to hash the plaintext given and compare that hash against one you have stored. The salts are stored in the hashes, and should be random. If you like, add a pepper. You should also make the workrate variable, so that you can change the workrate at any moment when needed and still have your system work.

如果像您说的那样无法实现此目的,则可以按以下方式解压缩哈希:

If, like you say, you have no way of implementing this, you can unpack the hash as follows:

function unpack_hash($hash) {
        $hash = base64_decode($hash);
        $split = str_split($hash, 64);
        return array("salt" => $split[1], "hash" => $split[0]);

这是因为SHA256是256位或64个十六进制字符.您可以始终假定前64个字符为哈希

This is because SHA256 is 256 bits, or 64 hex characters. You can just always assume the first 64 chars are the hash

这篇关于针对PHP中的SSHA256哈希验证密码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆