2013-02-01 122 views
1

對不起,這個很奇怪的問題。我理解用於傳輸數據的base64編碼(即MIME的Base64編碼)的目的,但我不知道是否需要對base64編碼我的鹽。我需要base64編碼我的鹽(哈希密碼)嗎?

我寫了一個實用工具類(抽象基類確實):

use Symfony\Component\Security\Core\Encoder\BasePasswordEncoder; 

abstract class AbstractCryptPasswordEncoder extends BasePasswordEncoder 
{ 
    /** 
    * @return string 
    */ 
    protected abstract function getSaltPrefix(); 

    /** 
    * @return string 
    */ 
    protected abstract function getSalt(); 

    /** 
    * {@inheritdoc} 
    */ 
    public function encodePassword($raw, $salt = null) 
    { 
     return crypt($raw, $this->getSaltPrefix().$this->getSalt()); 
    } 

    /** 
    * {@inheritdoc} 
    */ 
    public function isPasswordValid($encoded, $raw, $salt = null) 
    { 
     return $encoded === crypt($raw, $encoded); 
    } 
} 

真正的實現類將是:

class Sha512CryptPasswordEncoder extends AbstractCryptPasswordEncoder 
{ 
    /** 
    * @var string 
    */ 
    private $rounds; 

    /** 
    * @param null|int $rounds The number of hashing loops 
    */ 
    public function __construct($rounds = null) 
    { 
     $this->rounds = $rounds; 
    } 

    /** 
    * {@inheritdoc} 
    */ 
    protected function getSaltPrefix() 
    { 
     return sprintf('$6$%s', $this->rounds ? "rounds={$this->rounds}$" : ''); 
    } 

    /** 
    * {@inheritdoc} 
    */ 
    protected function getSalt() 
    { 
     return base64_encode(openssl_random_pseudo_bytes(12)); 
    } 
} 

的關鍵部分是鹽的產生,這將嵌入密碼:我是否需要base64_encode出於任何原因(存儲),假設它永遠不會通過電線發送?

+0

參考這個問題:http://stackoverflow.com/questions/401656/secure-hash-and-salt-for-php-passwords但是,沒有 - 你不應該在哈希密碼上使用base64。 –

回答

3

每個散列算法都需要給定字母表中的鹽,這意味着使用base64_encode()可能是正確的,但它通常不會使用完整字母表或返回不在此字母表中的字符。

以BCrypt爲例,這是一個很好的密碼散列算法(SHA-512不適合,因爲它太快),它接受除了'+'字符之外的所有base64編碼字符的字符。另一方面它接受'。'不屬於base64編碼字符串的字符。

PHP 5.5將準備好函數password_hash()password_verify(),使BCrypt的使用更容易,我真的可以推薦它們。還有一個compatibility pack可用於較老的PHP版本,在第121行中,您可以看到base64_encode()確實被使用,但之後所有無效的「+」字符都被替換爲允許的'。'。人物:

編碼鹽爲BCrypt:

$salt = str_replace('+', '.', base64_encode($buffer)); 
+0

+1爲一個很好的答案。關於兼容性包的一點不完全清楚,因此爲了其他人的利益,兼容包是一個可下載的庫,它爲PHP 5.3或5.4的用戶實現了PHP5.5'password_xxx()'函數。這意味着**任何目前支持的PHP版本的所有用戶都可以使用新的官方PHP密碼API **。 – SDC

+0

@SDC - 感謝您的評論,我試圖讓它更清楚一點。 – martinstoeckli

+0

優秀的答案,+1。雖然河豚鹽的要求對我來說很清楚(base64編碼隨機字節,'+'替換),但它仍不清楚sha512鹽的要求:原始字節?一些字母表? – gremo

1

BASE64用於將二進制數據編碼爲文本表示。它允許使用文本通道傳輸二進制數據。如果您想在數據庫中存儲散列密碼,則不必對其進行編碼 - 它已經是文本格式。