[英]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.