2013-03-05 27 views
9

Tôi đang học về hàm crypt() của PHP và đã chạy một số thử nghiệm với nó. Theo số this post, tôi nên sử dụng muối dài 22 ký tự. Tuy nhiên, tôi có thể sử dụng một chuỗi dài 23 ký tự với một số hạn chế. Khi tôi sử dụng chuỗi dài 22 ký tự, tôi luôn nhận được kết quả '$ 2y $ xxStringStringStringStri.HashHashHashHashHashHashHashHas'. Tôi biết thời kỳ này chỉ là một phần của muối.Tại sao tôi không nên sử dụng ký tự thứ 23 trong muối của hàm crypt()?

Có vẻ như nếu tôi sử dụng 23 ký tự thay vì chỉ 22, tôi có thể tạo thành công các băm khác nhau, nhưng chỉ có 4 kết quả khác nhau cho tất cả 64 ký tự. Ký tự thứ 23 "làm tròn" xuống gần 1/4 của ký tự 64 ký tự (ví dụ: ký tự thứ 23 là "W" và làm tròn xuống "O" hoặc bất kỳ số nào tròn xuống "u")

v---------------v---------------v---------------v--------------- 
./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890 

Tất cả bốn người trong số các chức năng hầm mộ tạo ra các muối tương tự:

crypt('Test123','$2y$09$AAAAAAAAAAAAAAAAAAAAAq'); 
crypt('Test123','$2y$09$AAAAAAAAAAAAAAAAAAAAAr'); 
crypt('Test123','$2y$09$AAAAAAAAAAAAAAAAAAAAAs'); 
crypt('Test123','$2y$09$AAAAAAAAAAAAAAAAAAAAAt'); 

Nhưng, lần này là khác nhau:

crypt('Test123','$2y$09$AAAAAAAAAAAAAAAAAAAAAu'); 

Vậy tại sao tôi không nên sử dụng ký tự thứ 23 khi nó có thể tạo thành những kết quả khác nhau? Có một số loại hành vi không ổn định trong PHP mà nên tránh bằng cách không sử dụng nó?

Để làm rõ về cách tôi đang đếm kí tự thứ 23 trong muối:

crypt('Test123','$2y$08$ABCDEFGHIJKLMNOPQRSTUV'); 
//  The salt is '$ABCDEFGHIJKLMNOPQRSTUV' 
//  Which will be treated as '$ABCDEFGHIJKLMNOPQRSTUO' 
+1

Có giải thích tốt về câu hỏi này: http://security.stackexchange.com/questions/20862/php-crypt-trims-the-salt-as-it-would-be-too-long –

+0

Cảm ơn bạn đã phản ứng này. Mặc dù điều này chỉ giải quyết những gì xảy ra với ký tự thứ 23 vì nó chỉ được rút ngắn do kích thước của các bit được cho phép trong hàm crypt(). Câu hỏi của tôi, theo một cách khác để hỏi, là "Tôi có nên sử dụng nhân vật thứ 23 ngay cả khi nó sẽ bị cắt thành hai bit?" hoặc một cách khác là "Có một trục trặc trong thuật toán của PHP mà tạo ra băm không chính xác bất cứ khi nào nhân vật thứ 23 được sử dụng?" – Andrew

Trả lời

2

Nó đã làm với va chạm băm. Khi bạn vượt quá 22 ký tự, dấu băm được tạo của bạn không còn độc đáo phụ thuộc vào NAMESPACE của thuật toán. Nói một cách khác, hơn 22 ký tự không dẫn đến bất kỳ sự bảo mật nào tăng lên và thực sự có thể làm giảm mức độ bảo mật của bạn.

+1

Dường như với tôi như nó cho biết thêm 2 bit bảo mật. Tôi vẫn có thể tạo ra các băm khác nhau bằng cách thay đổi các ký tự khác trong suốt muối trong khi rời khỏi ngày 23, hãy nói "a". Có một bài viết về việc tràn muối không? Ngay cả trên [php.net] (http://php.net/manual/en/function.crypt.php), họ sử dụng một ví dụ về một muối với hơn 22 ký tự. – Andrew

+1

Tất nhiên nó sẽ tạo ra các kết quả khác nhau nhưng nếu bạn sử dụng 23 ký tự thì có một chuỗi khác trên đó sẽ dẫn đến kết quả băm chính xác. Điều này được gọi là va chạm và bạn không muốn điều đó khi bạn đang cố giữ mọi thứ độc đáo. –

+0

Hmmm .... Tôi không chắc chắn làm thế nào để giải thích điều này, nhưng tôi có thể đảm bảo với bạn rằng sử dụng 23 ký tự trong một muối (mặc dù có những va chạm muối như bạn nói) là an toàn hơn so với sử dụng 22. Giải thích: Hãy nói chúng ta có hình thức cá blowfish nhỏ hơn. Trong loài cá nhỏ này, chúng ta có thể đặt một muối dài 1 ký tự, chẳng hạn như "a" hoặc "4" hoặc "I".Có 64 kết hợp khác nhau mà chúng ta có thể thực hiện với điều đó trước khi chúng ta bắt đầu bị va chạm với muối. Tuy nhiên, chúng ta chỉ có thể thêm 2 bit nữa (".", "O", "e", và "u") và biến một sự kết hợp của 64 muối duy nhất thành 256. Ngay cả khi không phải là bảng chữ cái đầy đủ, nó an toàn hơn. – Andrew

0

$ không phải là một phần của muối thực tế. Nó là một dấu phân cách.

Đối với mật mã Blowfish, định dạng là $ 2 [axy] $ log2Rounds $ [salt] [hash]. Bạn mô tả nó thêm a. - đó là bởi vì bạn đang thiếu ký tự cuối cùng. Muối của Blowfish là 128 bit. Bạn có thể sử dụng chỉ 126, có, nhưng bạn chỉ cần làm suy yếu muối không cần thiết.

+0

Nếu bạn thực sự sử dụng quá nhiều ký tự, bằng cách này, bạn hoàn toàn ổn với crypt() vì nó được thiết kế để sử dụng như crypt (mật khẩu, muối) cho crypt, cryptedPassword == crypt (mật khẩu, mật khẩu Mật khẩu) để xác minh, và nó thực hiện điều này bằng cách gắn băm vào muối trên đầu ra, và chỉ sử dụng các byte muối có liên quan trên đầu vào. Bạn thấy đấy, các nhân vật phụ sẽ không được sử dụng. – Zer

Các vấn đề liên quan