2013-02-03 77 views
3

你好,你可能知道PHP最近推出的password_hash內置最新版本。該文檔說:PHP的password_hash如何生成鹽?

如果省略,將會創建一個隨機鹽,並使用默認成本。

問題是用什麼樣的方法來添加鹽?

我很感興趣,因爲我想知道,如果鹽創建隨機這樣,當我存儲我的哈希密碼他們總是唯一

回答

8

鹽是隨機創建的。它們應該是統計獨特的。

要了解具體方法,請查看the C source code

在Windows上,它會嘗試使用php_win32_get_random_bytes()生成鹽:

BYTE *iv_b = (BYTE *) buffer; 
if (php_win32_get_random_bytes(iv_b, raw_length) == SUCCESS) { 
    buffer_valid = 1; 
} 

在Linux上,它會嘗試讀取/dev/urandom生成鹽:

int fd, n; 
size_t read_bytes = 0; 
fd = open("/dev/urandom", O_RDONLY); 
if (fd >= 0) { 
    while (read_bytes < raw_length) { 
     n = read(fd, buffer + read_bytes, raw_length - read_bytes); 
     if (n < 0) { 
      break; 
     } 
     read_bytes += (size_t) n; 
    } 
    close(fd); 
} 
if (read_bytes >= raw_length) { 
    buffer_valid = 1; 
} 

然後,在這些二,如果緩衝區無效(未滿,可能是部分),它使用rand()填充它。請注意,在實踐中,這是不可能發生的,它只是一個回退:現在

if (!buffer_valid) { 
    for (i = 0; i < raw_length; i++) { 
     buffer[i] ^= (char) (255.0 * php_rand(TSRMLS_C)/RAND_MAX); 
    } 
} 

,如果C是不是你的那杯茶,同樣的邏輯和算法PHP實現在my compat library

$buffer = ''; 
$raw_length = (int) ($required_salt_len * 3/4 + 1); 
$buffer_valid = false; 
if (function_exists('mcrypt_create_iv')) { 
    $buffer = mcrypt_create_iv($raw_length, MCRYPT_DEV_URANDOM); 
    if ($buffer) { 
     $buffer_valid = true; 
    } 
} 
if (!$buffer_valid && function_exists('openssl_random_pseudo_bytes')) { 
    $buffer = openssl_random_pseudo_bytes($raw_length); 
    if ($buffer) { 
     $buffer_valid = true; 
    } 
} 
if (!$buffer_valid && is_readable('/dev/urandom')) { 
    $f = fopen('/dev/urandom', 'r'); 
    $read = strlen($buffer); 
    while ($read < $raw_length) { 
     $buffer .= fread($f, $raw_length - $read); 
     $read = strlen($buffer); 
    } 
    fclose($f); 
    if ($read >= $raw_length) { 
     $buffer_valid = true; 
    } 
} 
if (!$buffer_valid || strlen($buffer) < $raw_length) { 
    $bl = strlen($buffer); 
    for ($i = 0; $i < $raw_length; $i++) { 
     if ($i < $bl) { 
      $buffer[$i] = $buffer[$i]^chr(mt_rand(0, 255)); 
     } else { 
      $buffer .= chr(mt_rand(0, 255)); 
     } 
    } 
} 

唯一的區別是,PHP版本將使用mcryptopenssl(如果安裝了任何一個)...