簡體   English   中英

針對PHP中的SSHA256哈希驗證密碼

[英]Validate a password against an SSHA256 hash in PHP

為了通過Dovecot進行身份驗證,我使用SSHA256哈希,但是我不知道如何針對現有哈希驗證給定密碼。 以下PHP函數(在Web上找到它們)用於創建SSHA256哈希:

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

我必須提取鹽,但是如何提取? 我完全迷失了解決問題的方式,對此有沒有人暗示?

感謝大家的幫助!

哦,對不起,我必須使用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

您需要將鹽與哈希值一起存儲。

當您需要驗證密碼時,您只需使用用戶輸入的密碼+存儲的鹽重新計算哈希值即可。 如果哈希匹配,則用戶輸入了正確的密碼。

對於您的格式, base64_decode使用base64_decode ,結果的最后4個字節將為salt。

您不應該將SHA系列用於密碼哈希。 它們速度很快 ,可以快速 散列文件 您需要使用pashword哈希來使其昂貴 使用bcrypt,PHPass或只使用我自己滾動的此類(但要等到您學會在其中學習漏洞時再使用):

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變量可變,以便可以在需要時隨時更改工作率,並且仍使系統正常工作。


如您所說,如果您無法實現此目的,則可以按以下方式解壓縮哈希:

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個字符為哈希

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM