2014-10-10 61 views
3

代碼:PHP password_hash函數鹽長21或22?

echo password_hash("stackoverflow", PASSWORD_DEFAULT, ['salt' => 'twenty-one-characters']); 

結果:

Warning: password_hash(): Provided salt is too short: 21 expecting 22 

代碼:

echo password_hash("stackoverflow", PASSWORD_DEFAULT, ['salt' => 'twenty-one-charactersA']); 

結果:

$2y$10$dHdlbnR5LW9uZS1jaGFyYOVyX13hK9eb4/KXMAkHsAJX..YR7t/32 

代碼:

echo password_hash("stackoverflow", PASSWORD_DEFAULT, ['salt' => 'twenty-one-charactersB']); 

$2y$10$dHdlbnR5LW9uZS1jaGFyYOVyX13hK9eb4/KXMAkHsAJX..YR7t/32 

問:

正如你看到的,通過追加A和B到21個字符串我們創建的22個字符兩種不同的鹽,但是,哈希值是一樣的!那第二十二個字被忽略了?如果它被忽略,爲什麼它要求22個字符的鹽?

+0

你爲什麼醃製自己而不使用默認? – 2014-10-10 08:44:30

+1

閱讀[blowfish]上的註釋(http://php.net/manual/en/function.crypt。php)默認算法,22字符鹽的細節 – 2014-10-10 08:48:28

回答

1

BCrypt期望的給定字母的鹽:./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz。如你所見,' - '不在其中,這就是你的鹽無效的原因。一個有效的鹽,你可以在散列值中看到純文本。

在大多數情況下,最好省略salt參數。如果沒有這個參數,該函數將從操作系統的隨機源生成一個加密安全的鹽。

password_hash("stackoverflow", PASSWORD_DEFAULT); 

然而,如果你說BCrypt沒有使用完整的22個字符,你是對的。看來BCrypt只使用126位鹽而不是用22位base64編碼字符得到的128位。欲瞭解更多信息,你可以看看這個討論Why does crypt/blowfish generate the same hash...

+0

Bcrypt確實使用了全部22個字符。但它只使用了第22位的前2位...... – ircmaxell 2014-12-20 14:53:44

+0

@ircmaxell - 是的,這實際上是我的意思,我的答案有什麼問題?在任何情況下,我都會記住你的優秀鏈接。 – martinstoeckli 2014-12-20 15:42:46

0

首先,不提供你自己的鹽。你不會比圖書館做得更好。並使用靜態鹽(如你在例子中所做的)妥協安全。讓它產生自己的鹽(順便說一句,我相信讓鹽進入是我在API中犯的最大錯誤)。

只要21對22個字符,給this answer一讀。

基本上,鹽是base64編碼的。這意味着鹽的每6位被編碼爲8位。所以編碼鹽的每個字節都是6位。

21個字符是126位。這意味着只使用第22個字符的一部分(前2個解碼位)。與AB獲得相同散列的原因在於,兩個字符的前2位是相同的。

實際上,第22個字節只有4個獨特的哈希值。