Băm an toàn và muối cho mật khẩu PHP


1174

Hiện tại người ta nói rằng MD5 không an toàn một phần. Cân nhắc điều này, tôi muốn biết nên sử dụng cơ chế nào để bảo vệ mật khẩu.

Câu hỏi này, Có phải băm đôi đã băm một mật khẩu kém an toàn hơn là chỉ băm nó một lần không? gợi ý rằng băm nhiều lần có thể là một ý tưởng tốt, trong khi Làm thế nào để thực hiện bảo vệ mật khẩu cho các tệp riêng lẻ? đề nghị sử dụng muối.

Tôi đang sử dụng PHP. Tôi muốn một hệ thống mã hóa mật khẩu an toàn và nhanh chóng. Băm mật khẩu một triệu lần có thể an toàn hơn, nhưng cũng chậm hơn. Làm thế nào để đạt được sự cân bằng tốt giữa tốc độ và an toàn? Ngoài ra, tôi muốn kết quả có số lượng ký tự không đổi.

  1. Cơ chế băm phải có sẵn trong PHP
  2. Nó phải an toàn
  3. Nó có thể sử dụng muối (trong trường hợp này, tất cả các muối đều tốt như nhau? Có cách nào để tạo ra muối tốt không?)

Ngoài ra, tôi có nên lưu trữ hai trường trong cơ sở dữ liệu (một trường sử dụng MD5 và một trường khác sử dụng SHA chẳng hạn)? Nó sẽ làm cho nó an toàn hơn hoặc không an toàn hơn?

Trong trường hợp tôi không đủ rõ ràng, tôi muốn biết nên sử dụng chức năng băm nào và cách chọn một loại muối tốt để có cơ chế bảo vệ mật khẩu nhanh chóng và an toàn.

Các câu hỏi liên quan không hoàn toàn bao gồm câu hỏi của tôi:

Sự khác biệt giữa SHA và MD5 trong
Mã hóa mật khẩu đơn giản PHP
Phương pháp lưu trữ khóa, mật khẩu an toàn cho asp.net
Bạn sẽ triển khai mật khẩu muối trong Tomcat 5.5 như thế nào


13
openwall.com/phpass cũng là thư viện rất tốt
Alfred

51
Md5 hiện tại hoàn toàn không an toàn
JqueryToAddNumbers

3
@NSAwgieGuy Điều đó phụ thuộc vào việc bạn đang sử dụng nó để làm gì. Chắc chắn là không phù hợp với cầu vồng hoặc chỉ đơn giản là không có mật khẩu MD5, nhưng với việc xử lý muối tốt, việc xây dựng một bảng cầu vồng để bẻ khóa nhanh các mật khẩu là vô cùng khó khăn và lực lượng vũ phu là không có tác dụng.
Craig Ringer

12
PHP 5.5+ có hàm băm mật khẩu an toàn được xây dựng trong php.net/manual/en/feft.password-hash.php
Terence Johnson

Câu trả lời:


982

TUYÊN BỐ TỪ CHỐI : Câu trả lời này được viết vào năm 2008.

Kể từ đó, PHP đã cho chúng ta password_hashpassword_verify , kể từ khi được giới thiệu, chúng là phương pháp kiểm tra và băm mật khẩu được đề xuất.

Lý thuyết của câu trả lời vẫn là một đọc tốt mặc dù.

TL; DR

Không

  • Đừng giới hạn những ký tự mà người dùng có thể nhập cho mật khẩu. Chỉ có những kẻ ngốc mới làm điều này.
  • Đừng giới hạn độ dài của mật khẩu. Nếu người dùng của bạn muốn có một câu với supercalifragilisticexpialidocious trong đó, đừng ngăn họ sử dụng nó.
  • Không tước hoặc thoát HTML và các ký tự đặc biệt trong mật khẩu.
  • Không bao giờ lưu trữ mật khẩu người dùng của bạn trong văn bản đơn giản.
  • Không bao giờ gửi email mật khẩu cho người dùng của bạn trừ khi họ mất mật khẩu và bạn đã gửi mật khẩu tạm thời.
  • Không bao giờ, bao giờ đăng nhập mật khẩu theo bất kỳ cách nào.
  • Không bao giờ băm mật khẩu với SHA1 hoặc MD5 hoặc thậm chí SHA256! Bánh quy hiện đại có thể vượt quá 60 và 180 tỷ băm / giây (tương ứng).
  • Không trộn bcrypt và với đầu ra thô của hàm băm () , sử dụng đầu ra hex hoặc base64_encode. (Điều này áp dụng cho bất kỳ đầu vào nào có thể có sự bất hảo \0trong đó, điều này có thể làm suy yếu nghiêm trọng an ninh.)

Liều dùng

  • Sử dụng tiền điện tử khi bạn có thể; bcrypt nếu bạn không thể.
  • Sử dụng PBKDF2 nếu bạn không thể sử dụng bcrypt hoặc scrypt, với băm SHA2.
  • Đặt lại mật khẩu của mọi người khi cơ sở dữ liệu bị xâm phạm.
  • Thực hiện độ dài tối thiểu 8-10 ký tự hợp lý, cộng với yêu cầu ít nhất 1 chữ cái viết hoa, 1 chữ cái viết thường, một số và ký hiệu. Điều này sẽ cải thiện entropy của mật khẩu, do đó làm cho nó khó bị bẻ khóa hơn. (Xem phần "Điều gì tạo ra một mật khẩu tốt?" Cho một số tranh luận.)

Tại sao băm mật khẩu?

Mục tiêu đằng sau việc băm mật khẩu rất đơn giản: ngăn chặn truy cập độc hại vào tài khoản người dùng bằng cách xâm phạm cơ sở dữ liệu. Vì vậy, mục tiêu của việc băm mật khẩu là để ngăn chặn tin tặc hoặc kẻ bẻ khóa bằng cách khiến chúng tốn quá nhiều thời gian hoặc tiền bạc để tính mật khẩu văn bản đơn giản. Và thời gian / chi phí là yếu tố ngăn chặn tốt nhất trong kho vũ khí của bạn.

Một lý do khác mà bạn muốn băm tốt, mạnh mẽ trên tài khoản người dùng là cung cấp cho bạn đủ thời gian để thay đổi tất cả mật khẩu trong hệ thống. Nếu cơ sở dữ liệu của bạn bị xâm phạm, bạn sẽ cần đủ thời gian để ít nhất khóa hệ thống, nếu không thay đổi mọi mật khẩu trong cơ sở dữ liệu.

Jeremiah Grossman, CTO của Whitehat Security, đã tuyên bố trên blog White Hat Security sau khi khôi phục mật khẩu gần đây yêu cầu phá vỡ sự bảo vệ mật khẩu của anh ta:

Thật thú vị, khi sống trong cơn ác mộng này, tôi đã học được RẤT NHIỀU tôi không biết về việc bẻ khóa mật khẩu, lưu trữ và độ phức tạp. Tôi đã đánh giá cao lý do tại sao việc lưu trữ mật khẩu lại quan trọng hơn nhiều so với độ phức tạp của mật khẩu. Nếu bạn không biết mật khẩu của mình được lưu trữ như thế nào, thì tất cả những gì bạn thực sự có thể phụ thuộc vào là sự phức tạp. Đây có thể là kiến ​​thức phổ biến đối với mật khẩu và tiền điện tử, nhưng đối với chuyên gia trung bình Infecec hoặc Web Security, tôi rất nghi ngờ điều đó.

(Nhấn mạnh của tôi.)

Điều gì làm cho một mật khẩu tốt anyway?

Entropy . (Không phải tôi hoàn toàn đăng ký theo quan điểm của Randall.)

Nói tóm lại, entropy là bao nhiêu biến thể trong mật khẩu. Khi mật khẩu chỉ là chữ cái La Mã viết thường, đó chỉ là 26 ký tự. Đó không phải là nhiều biến thể. Mật khẩu Alpha-số tốt hơn, với 36 ký tự. Nhưng cho phép chữ hoa và chữ thường, với các ký hiệu, là khoảng 96 ký tự. Điều đó tốt hơn nhiều so với chỉ các chữ cái. Một vấn đề là, để làm cho mật khẩu của chúng ta trở nên đáng nhớ, chúng ta chèn các mẫu mà làm giảm entropy. Giáo sư!

Mật khẩu entropy là gần đúng dễ dàng. Sử dụng đầy đủ các ký tự ascii (khoảng 96 ký tự có thể đánh máy) mang lại mức entropy là 6,6 cho mỗi ký tự, với 8 ký tự cho mật khẩu vẫn còn quá thấp (52.679 bit của entropy) để bảo mật trong tương lai. Nhưng tin tốt là: mật khẩu dài hơn và mật khẩu có ký tự unicode, thực sự làm tăng entropy của mật khẩu và làm cho nó khó bị bẻ khóa hơn.

Có một cuộc thảo luận dài hơn về entropy mật khẩu trên trang web Crypto StackExchange . Một tìm kiếm Google tốt cũng sẽ cho ra rất nhiều kết quả.

Trong các bình luận tôi đã nói chuyện với @popnoodles, người chỉ ra rằng việc thực thi chính sách mật khẩu có độ dài X với X nhiều chữ cái, số, ký hiệu, v.v., thực sự có thể làm giảm entropy bằng cách làm cho lược đồ mật khẩu trở nên dễ đoán hơn. Tôi thực sự đồng ý. Randomess, thực sự ngẫu nhiên nhất có thể, luôn là giải pháp an toàn nhất nhưng ít đáng nhớ nhất.

Cho đến nay tôi đã có thể nói, làm cho mật khẩu tốt nhất thế giới là một Catch-22. Nó không đáng nhớ, quá dễ đoán, quá ngắn, quá nhiều ký tự unicode (khó gõ trên thiết bị Windows / Mobile), quá dài, v.v. Không có mật khẩu nào thực sự đủ tốt cho mục đích của chúng tôi, vì vậy chúng tôi phải bảo vệ chúng như thể chúng đã ở Fort Knox.

Thực hành tốt nhất

Bcrypt và tiền điện tử là những thực tiễn tốt nhất hiện nay. Scrypt sẽ tốt hơn bcrypt về thời gian, nhưng nó chưa được xem là tiêu chuẩn của Linux / Unix hoặc bởi các máy chủ web và chưa có đánh giá sâu về thuật toán của nó được đăng. Tuy nhiên, tương lai của thuật toán có vẻ đầy hứa hẹn. Nếu bạn đang làm việc với Ruby, có một viên ngọc mã hóa sẽ giúp bạn thoát ra và Node.js hiện có gói mã hóa riêng . Bạn có thể sử dụng Scrypt trong PHP thông qua tiện ích mở rộng Scrypt hoặc tiện ích mở rộng Libsodium (cả hai đều có sẵn trong PECL).

Tôi đặc biệt khuyên bạn nên đọc tài liệu về chức năng mật mã nếu bạn muốn hiểu cách sử dụng bcrypt hoặc tìm cho mình một trình bao bọc tốt hoặc sử dụng một cái gì đó như PHPASS để triển khai hợp pháp hơn. Tôi khuyên bạn nên tối thiểu 12 vòng bcrypt, nếu không phải là 15 đến 18.

Tôi đã thay đổi suy nghĩ về việc sử dụng bcrypt khi tôi biết rằng bcrypt chỉ sử dụng lịch biểu chính của blowfish, với cơ chế chi phí biến đổi. Cái sau cho phép bạn tăng chi phí để bắt bẻ mật khẩu bằng cách tăng lịch trình khóa đắt tiền của blowfish.

Thực hành trung bình

Tôi gần như không thể tưởng tượng được tình huống này nữa. PHPASS hỗ trợ PHP 3.0.18 đến 5.3, vì vậy có thể sử dụng trên hầu hết mọi cài đặt có thể tưởng tượng được và nên được sử dụng nếu bạn không biết chắc chắn rằng môi trường của bạn hỗ trợ bcrypt.

Nhưng giả sử rằng bạn không thể sử dụng bcrypt hoặc PHPASS. Sau đó thì sao?

Hãy thử triển khai PDKBF2 với số vòng tối đa mà môi trường / ứng dụng / nhận thức của người dùng của bạn có thể chịu đựng được. Số thấp nhất tôi muốn giới thiệu là 2500 vòng. Ngoài ra, hãy đảm bảo sử dụng hash_hmac () nếu có sẵn để làm cho thao tác khó tái tạo hơn.

Thực tiễn trong tương lai

Đến với PHP 5.5 là một thư viện bảo vệ mật khẩu đầy đủ giúp tóm tắt mọi khó khăn khi làm việc với bcrypt. Mặc dù hầu hết chúng ta bị mắc kẹt với PHP 5.2 và 5.3 trong hầu hết các môi trường phổ biến, đặc biệt là các máy chủ được chia sẻ, @ircmaxell đã xây dựng một lớp tương thích cho API sắp tới tương thích ngược với PHP 5.3.7.

Tóm tắt và từ chối mật mã

Sức mạnh tính toán cần thiết để thực sự bẻ khóa mật khẩu băm không tồn tại. Cách duy nhất để máy tính "bẻ khóa" mật khẩu là tạo lại nó và mô phỏng thuật toán băm được sử dụng để bảo mật nó. Tốc độ của hàm băm có liên quan tuyến tính với khả năng bị ép buộc. Tệ hơn nữa, hầu hết các thuật toán băm có thể dễ dàng song song để thực hiện nhanh hơn. Đây là lý do tại sao các chương trình tốn kém như bcrypt và tiền điện tử rất quan trọng.

Bạn không thể thấy trước tất cả các mối đe dọa hoặc con đường tấn công, và vì vậy bạn phải nỗ lực hết sức để bảo vệ người dùng của mình lên phía trước . Nếu bạn không, thì bạn thậm chí có thể bỏ lỡ sự thật rằng bạn đã bị tấn công cho đến khi quá muộn ... và bạn phải chịu trách nhiệm . Để tránh tình trạng đó, hãy hành động hoang tưởng để bắt đầu. Tấn công phần mềm của riêng bạn (nội bộ) và cố gắng đánh cắp thông tin đăng nhập của người dùng hoặc sửa đổi tài khoản của người dùng khác hoặc truy cập dữ liệu của họ. Nếu bạn không kiểm tra tính bảo mật của hệ thống, thì bạn không thể đổ lỗi cho bất kỳ ai trừ chính bạn.

Cuối cùng: Tôi không phải là một nhà mật mã học. Bất cứ điều gì tôi đã nói là ý kiến ​​của tôi, nhưng tôi tình cờ nghĩ rằng nó dựa trên ý thức chung của ol ... và rất nhiều việc đọc. Hãy nhớ rằng, hãy hoang tưởng nhất có thể, làm cho mọi thứ trở nên khó xâm nhập nhất có thể, và sau đó, nếu bạn vẫn lo lắng, hãy liên hệ với một hacker mũ trắng hoặc nhà mật mã để xem họ nói gì về mã / hệ thống của bạn.


9
một bí mật không giúp ích gì vì mật khẩu DB của bạn dù sao cũng được coi là bí mật - nếu họ có thể nắm giữ DB đó, họ cũng có thể tìm thấy bất cứ bí mật nào bạn đang sử dụng. Tuy nhiên, điều quan trọng là muối là ngẫu nhiên.
frankodwyer

2
lưu ý, thực sự không phải là 'sức mạnh tính toán để giải mã' chưa tồn tại. vì hầu hết mật khẩu là các từ trong từ điển hoặc từ điển có nguồn gốc, một cuộc tấn công dựa trên từ điển thường rất hiệu quả (do đó việc sử dụng các chính sách mật khẩu và số lần lặp).
frankodwyer

6
@wicked flea, tôi không tranh luận với bạn. Chỉ cần chỉ ra làm thế nào phức tạp và phức tạp khu vực này của công việc của chúng tôi là. Tôi tiếp tục hy vọng được đi học bởi cách thực hành tốt nhất, thông minh nhất, cuối cùng để thiết lập hệ thống quản lý nội dung của một trang web nhỏ. Tôi vẫn đang học ở đây. ... Mỗi khi tôi đọc được điều gì đó có ý nghĩa, tôi sẽ sớm nhận thấy 5 bài viết khác mâu thuẫn với nó. vòng tròn đó nhanh chóng chóng mặt :)
m42

4
Sửa đổi thú vị. ID người dùng (giả sử, BIGINT tự động tăng) có phải là một điểm tốt không? Hoặc vì nó không ngẫu nhiên nên nó không tốt? Ngoài ra, tôi sẽ phải lưu trữ nonce cho mỗi người dùng trong cơ sở dữ liệu ... Liệu khóa trang web + nonce + HMAC có cung cấp bảo mật được cải thiện đáng kể đối với hàm băm (có ID người dùng) được lặp đi lặp lại nhiều lần không? Tương tự như vậy, việc lặp lại HMAC nhiều lần có tốt cho bảo mật không?
luiscubal

4
Gửi mật khẩu tạm thời qua email yêu cầu người dùng thay đổi mật khẩu lần đầu tiên họ sử dụng và gửi liên kết "an toàn" qua email cho phép họ đặt mật khẩu cũng có rủi ro như nhau. Trong mọi trường hợp, bất kỳ ai chặn email đều có thể truy cập vào tài khoản miễn là họ sử dụng liên kết hoặc mật khẩu trước khi người nhận dự định thực hiện.
Tim Gautier

138

Câu trả lời ngắn hơn và an toàn hơn nhiều - đừng viết cơ chế mật khẩu của riêng bạn , hãy sử dụng cơ chế đã thử và đã thử.

  • PHP 5.5 trở lên: password_hash () có chất lượng tốt và là một phần của lõi PHP.
  • Các phiên bản PHP cũ hơn: Thư viện phpass của OpenWall tốt hơn nhiều so với hầu hết mã tùy chỉnh - được sử dụng trong WordPress, Drupal, v.v.

Hầu hết các lập trình viên chỉ không có chuyên môn để viết mã liên quan đến tiền điện tử một cách an toàn mà không giới thiệu các lỗ hổng.

Tự kiểm tra nhanh: kéo dài mật khẩu là gì và bạn nên sử dụng bao nhiêu lần lặp? Nếu bạn không biết câu trả lời, bạn nên sử dụng password_hash(), vì việc mở rộng mật khẩu hiện là một tính năng quan trọng của cơ chế mật khẩu do CPU nhanh hơn nhiều và việc sử dụng GPU và GPU để phá mật khẩu với tốc độ hàng tỷ lần đoán mỗi giây (với GPU ).

Ví dụ: bạn có thể bẻ khóa tất cả mật khẩu Windows 8 ký tự trong 6 giờ bằng 25 GPU được cài đặt trong 5 máy tính để bàn. Đây là cách bắt buộc, tức là liệt kê và kiểm tra mọi mật khẩu Windows 8 ký tự , bao gồm các ký tự đặc biệt và không phải là một cuộc tấn công từ điển. Đó là vào năm 2012, tính đến năm 2018, bạn có thể sử dụng ít GPU hơn hoặc bẻ khóa nhanh hơn với 25 GPU.

Ngoài ra còn có nhiều cuộc tấn công bảng cầu vồng vào mật khẩu Windows chạy trên CPU thông thường và rất nhanh. Tất cả điều này là do Windows vẫn không muối hoặc kéo dài mật khẩu của nó, ngay cả trong Windows 10 - không mắc lỗi tương tự như Microsoft đã làm!

Xem thêm:

  • câu trả lời tuyệt vời với nhiều hơn về lý do tại sao password_hash()hoặc phpasslà cách tốt nhất để đi.
  • bài viết blog tốt đưa ra đề xuất 'các yếu tố công việc' (số lần lặp) cho các thuật toán chính bao gồm bcrypt, scrypt và PBKDF2.

1
nhưng các hệ thống này được biết đến nhiều hơn và có thể đã bị xâm phạm. nhưng nó sẽ làm cho chính bạn khi bạn không biết bạn đang làm gì.
JqueryToAddNumbers

14
Re "các hệ thống này được biết đến nhiều hơn và có thể đã bị xâm phạm" - không có lý do gì một hệ thống được thiết kế tốt để xác thực sẽ trở thành "đã bị xâm phạm" chỉ vì nó được biết đến nhiều hơn. Các thư viện như phpass được viết bởi các chuyên gia và được xem xét chi tiết bởi nhiều người - thực tế họ nổi tiếng đi cùng với đánh giá chi tiết của những người khác nhau và có nhiều khả năng có nghĩa là họ an toàn.
RichVel

Với các băm mật khẩu gần đây từ LinkedIn, Last.fm và những người khác, điều này là khá thời sự. Bạn đang ở một công ty tốt trong việc không biết cách viết cơ chế mật khẩu của riêng bạn!
RichVel

3
@PP - theo tôi, khả năng thuật toán băm mật khẩu được đánh giá ngang hàng có cửa sau NSA là rất thấp, theo quan điểm của tôi. Cơ hội của một người không phải là một chuyên gia về tiền điện tử thực sự viết một cơ chế băm mật khẩu mới mà không có các lỗ hổng khác là thấp hơn nhiều. Và ứng dụng web điển hình chỉ sử dụng băm MD5 hoặc SHA-1, điều này thật tồi tệ - ngay cả cuốn sách Bảo mật PHP cần thiết tuyệt vời khác của Chris Shiflett cũng khuyến nghị MD5 ...
RichVel

1
@RichVel - Hàm password_hash (). Như đã đề cập trước đó, nó được tích hợp vào lõi PHP (aka / ext / standard).
CubicleSoft 15/03/2015

43

Tôi sẽ không lưu trữ mật khẩu được băm theo hai cách khác nhau, bởi vì sau đó hệ thống ít nhất là yếu nhất trong các thuật toán băm được sử dụng.


không cho băm mật khẩu. Kẻ tấn công chỉ cần phá vỡ một hàm băm để lấy lại mật khẩu. dù sao thì vấn đề vẫn là vì MD5 và SHA1 không có bất kỳ sự phá vỡ thực tế nào trong kịch bản mật khẩu.
frankodwyer

2
xin lỗi, tôi đã đọc sai câu trả lời của bạn khi khuyên bạn nên sử dụng hai hàm băm ... thực tế bạn đã đúng. Sử dụng hai băm làm suy yếu hệ thống trong trường hợp mật khẩu, vì chúng chỉ cần phá vỡ hàm băm yếu hơn.
frankodwyer

40

Kể từ PHP 5.5, PHP có các chức năng đơn giản, an toàn để băm và xác minh mật khẩu, password_hash ()password_verify ()

$password = 'anna';
$hash = password_hash($password, PASSWORD_DEFAULT);
$expensiveHash = password_hash($password, PASSWORD_DEFAULT, array('cost' => 20));

password_verify('anna', $hash); //Returns true
password_verify('anna', $expensiveHash); //Also returns true
password_verify('elsa', $hash); //Returns false

Khi password_hash()được sử dụng, nó tạo ra một loại muối ngẫu nhiên và đưa nó vào hàm băm xuất ra (cùng với chi phí và thuật toán được sử dụng.) password_verify()Sau đó đọc hàm băm đó và xác định phương pháp mã hóa và muối được sử dụng, và xác minh nó dựa trên mật khẩu văn bản được cung cấp.

Cung cấp các PASSWORD_DEFAULThướng dẫn PHP để sử dụng thuật toán băm mặc định của phiên bản PHP đã cài đặt. Chính xác thuật toán nào có nghĩa là sẽ thay đổi theo thời gian trong các phiên bản trong tương lai, do đó nó sẽ luôn là một trong những thuật toán mạnh nhất hiện có.

Việc tăng chi phí (mặc định là 10) làm cho hàm băm trở nên khó khăn hơn nhưng cũng có nghĩa là tạo ra các giá trị băm và xác minh mật khẩu đối với chúng sẽ giúp ích nhiều hơn cho CPU của máy chủ của bạn.

Lưu ý rằng mặc dù thuật toán băm mặc định có thể thay đổi, các băm cũ sẽ tiếp tục xác minh tốt vì thuật toán được sử dụng được lưu trữ trong hàm băm và password_verify()chọn ra nó.


33

Mặc dù câu hỏi đã được trả lời, tôi chỉ muốn nhắc lại rằng muối được sử dụng để băm nên là ngẫu nhiên và không giống như địa chỉ email như được đề xuất trong câu trả lời đầu tiên.

Có thêm lời giải thích tại- http://www.pOLLalsecurity.com/blog/password-hashing-salt-should-it-be-random/

Gần đây tôi đã có một cuộc thảo luận về việc băm mật khẩu được muối với các bit ngẫu nhiên có an toàn hơn so với mật khẩu được muối với muối có thể đoán hoặc đã biết. Hãy xem: Nếu mật khẩu lưu trữ hệ thống bị xâm phạm cũng như hệ thống lưu trữ muối ngẫu nhiên, kẻ tấn công sẽ có quyền truy cập vào hàm băm cũng như muối, do đó, liệu muối có ngẫu nhiên hay không, không thành vấn đề. Kẻ tấn công sẽ có thể tạo các bảng cầu vồng được tính toán trước để bẻ khóa hàm băm. Ở đây có phần thú vị - nó không quá tầm thường để tạo các bảng được tính toán trước. Hãy để chúng tôi lấy ví dụ về mô hình bảo mật WPA. Mật khẩu WPA của bạn thực sự không bao giờ được gửi đến Điểm truy cập không dây. Thay vào đó, nó được băm với SSID của bạn (tên mạng như Linksys, Dlink, v.v.). Một lời giải thích rất tốt về cách làm việc này là ở đây. Để lấy lại mật khẩu từ hàm băm, bạn sẽ cần biết mật khẩu cũng như muối (tên mạng). Church of Wifi đã tính toán sẵn các bảng băm có 1000 SSID hàng đầu và khoảng 1 triệu mật khẩu. Kích thước của tất cả các bảng là khoảng 40 GB. Như bạn có thể đọc trên trang của họ, ai đó đã sử dụng 15 mảng FGPA trong 3 ngày để tạo các bảng này. Giả sử nạn nhân đang sử dụng SSID với tên là Hồi a387csf3 và mật khẩu là Số 123456, liệu nó có bị bẻ khóa bởi các bảng đó không? Không! .. nó không thể. Ngay cả khi mật khẩu yếu, các bảng không có băm cho SSID a387csf3. Đây là vẻ đẹp của việc có muối ngẫu nhiên. Nó sẽ ngăn chặn các cracker phát triển mạnh trên các bảng được tính toán trước. Nó có thể ngăn chặn một hacker quyết tâm? Chắc là không. Nhưng sử dụng muối ngẫu nhiên sẽ cung cấp thêm lớp phòng thủ. Trong khi chúng ta đang ở trong chủ đề này, chúng ta hãy thảo luận về lợi thế bổ sung của việc lưu trữ muối ngẫu nhiên trên một hệ thống riêng biệt. Kịch bản # 1: Băm mật khẩu được lưu trữ trên hệ thống X và các giá trị muối được sử dụng để băm được lưu trữ trên hệ thống Y. Các giá trị muối này có thể đoán được hoặc đã biết (ví dụ: tên người dùng) Kịch bản # 2: Băm mật khẩu được lưu trữ trên hệ thống X và giá trị muối được sử dụng cho băm được lưu trữ trên hệ thống Y. Các giá trị muối này là ngẫu nhiên. Trong trường hợp hệ thống X đã bị xâm phạm, như bạn có thể đoán, có một lợi thế rất lớn khi sử dụng muối ngẫu nhiên trên một hệ thống riêng biệt (Kịch bản # 2). Kẻ tấn công sẽ cần phải đoán các giá trị bổ sung để có thể bẻ khóa băm. Nếu sử dụng muối 32 bit, 2 ^ 32 = 4.294.967.296 (khoảng 4.2 tỷ) lần lặp sẽ có thể được yêu cầu cho mỗi mật khẩu được đoán. Băm mật khẩu được lưu trữ trên hệ thống X và các giá trị muối được sử dụng để băm được lưu trữ trên hệ thống Y. Các giá trị muối này có thể đoán được hoặc đã biết (ví dụ: tên người dùng) Kịch bản # 2: Băm mật khẩu được lưu trữ trên hệ thống X và các giá trị muối được sử dụng để băm được lưu trữ trên hệ thống Y. Những giá trị muối này là ngẫu nhiên. Trong trường hợp hệ thống X đã bị xâm phạm, như bạn có thể đoán, có một lợi thế rất lớn khi sử dụng muối ngẫu nhiên trên một hệ thống riêng biệt (Kịch bản # 2). Kẻ tấn công sẽ cần phải đoán các giá trị bổ sung để có thể bẻ khóa băm. Nếu sử dụng muối 32 bit, 2 ^ 32 = 4.294.967.296 (khoảng 4.2 tỷ) lần lặp sẽ có thể được yêu cầu cho mỗi mật khẩu được đoán. Băm mật khẩu được lưu trữ trên hệ thống X và các giá trị muối được sử dụng để băm được lưu trữ trên hệ thống Y. Các giá trị muối này có thể đoán được hoặc đã biết (ví dụ: tên người dùng) Kịch bản # 2: Băm mật khẩu được lưu trữ trên hệ thống X và các giá trị muối được sử dụng để băm được lưu trữ trên hệ thống Y. Những giá trị muối này là ngẫu nhiên. Trong trường hợp hệ thống X đã bị xâm phạm, như bạn có thể đoán, có một lợi thế rất lớn khi sử dụng muối ngẫu nhiên trên một hệ thống riêng biệt (Kịch bản # 2). Kẻ tấn công sẽ cần phải đoán các giá trị bổ sung để có thể bẻ khóa băm. Nếu sử dụng muối 32 bit, 2 ^ 32 = 4.294.967.296 (khoảng 4.2 tỷ) lần lặp sẽ có thể được yêu cầu cho mỗi mật khẩu được đoán. Những giá trị muối này là ngẫu nhiên. Trong trường hợp hệ thống X đã bị xâm phạm, như bạn có thể đoán, có một lợi thế rất lớn khi sử dụng muối ngẫu nhiên trên một hệ thống riêng biệt (Kịch bản # 2). Kẻ tấn công sẽ cần phải đoán các giá trị bổ sung để có thể bẻ khóa băm. Nếu sử dụng muối 32 bit, 2 ^ 32 = 4.294.967.296 (khoảng 4.2 tỷ) lần lặp sẽ có thể được yêu cầu cho mỗi mật khẩu được đoán. Những giá trị muối này là ngẫu nhiên. Trong trường hợp hệ thống X đã bị xâm phạm, như bạn có thể đoán, có một lợi thế rất lớn khi sử dụng muối ngẫu nhiên trên một hệ thống riêng biệt (Kịch bản # 2). Kẻ tấn công sẽ cần phải đoán các giá trị bổ sung để có thể bẻ khóa băm. Nếu sử dụng muối 32 bit, 2 ^ 32 = 4.294.967.296 (khoảng 4.2 tỷ) lần lặp sẽ có thể được yêu cầu cho mỗi mật khẩu được đoán.


7
Ngay cả khi kẻ tấn công nhận được muối, chuỗi "sitealt: usersalt: password" vẫn chống lại các bảng được tính toán trước, vì kẻ tấn công cần tạo các bảng cho mọi người dùng (do đó, cuộc tấn công trở nên chậm hơn), trừ khi tất nhiên là một người dùng cụ thể đang được nhắm mục tiêu ...
luiscubal

Về "Ngay cả khi kẻ tấn công nhận được muối, một chuỗi" sitealt: usersalt: password "vẫn chống lại các bảng được tính toán trước", hoàn toàn đồng ý. Quan điểm của tôi là các trang web nếu được tạo ngẫu nhiên và lâu dài, sẽ làm cho hệ thống an toàn hơn so với các trang web (trang web) có thể dự đoán được. Tôi đã thấy một số người khuyên bạn nên sử dụng id email, v.v. như muối và tôi không khuyến khích điều đó.
Gaurav Kumar

Bạn đã bỏ lỡ những gì tôi viết ban đầu. Tôi đã nói sử dụng một nonce ngẫu nhiên, được lưu trữ với hồ sơ, CỘNG địa chỉ email. Việc bổ sung địa chỉ email làm cho entropy thêm cho tin tặc hoạt động. Kể từ đó tôi đã viết lại câu trả lời của mình ủng hộ bcrypt.
Robert K

28

Tôi chỉ muốn chỉ ra rằng PHP 5.5 bao gồm API băm mật khẩu cung cấp trình bao bọc xung quanh crypt(). API này đơn giản hóa đáng kể nhiệm vụ băm, xác minh và xử lý lại băm mật khẩu. Tác giả cũng đã phát hành một gói tương thích (dưới dạng một tệp password.php duy nhất mà bạn chỉ cần requiresử dụng), cho những người sử dụng PHP 5.3.7 trở lên và muốn sử dụng ngay bây giờ.

Hiện tại, nó chỉ hỗ trợ BCRYPT, nhưng nó nhằm mục đích dễ dàng mở rộng để bao gồm các kỹ thuật băm mật khẩu khác và vì kỹ thuật và chi phí được lưu trữ như một phần của hàm băm, các thay đổi đối với kỹ thuật / giá trị băm ưa thích của bạn sẽ không làm mất hiệu lực băm hiện tại, khung sẽ tự động, sử dụng đúng kỹ thuật / chi phí khi xác nhận. Nó cũng xử lý việc tạo ra muối "an toàn" nếu bạn không xác định rõ ràng của riêng bạn.

API hiển thị bốn chức năng:

  • password_get_info() - trả về thông tin về hàm băm đã cho
  • password_hash() - tạo một mật khẩu băm
  • password_needs_rehash()- kiểm tra xem hàm băm đã cho có khớp với các tùy chọn đã cho không. Hữu ích để kiểm tra xem hàm băm có phù hợp với sơ đồ kỹ thuật / chi phí hiện tại của bạn không, cho phép bạn thử lại nếu cần thiết
  • password_verify() - xác minh rằng mật khẩu khớp với hàm băm

Hiện tại, các hàm này chấp nhận các hằng số mật khẩu PASSWORD_BCRYPT và PASSWORD_DEFAULT, đồng nghĩa với hiện tại, sự khác biệt là PASSWORD_DEFAULT "có thể thay đổi trong các bản phát hành PHP mới hơn khi các thuật toán băm mới hơn, mạnh hơn được hỗ trợ." Sử dụng PASSWORD_DEFAULT và password_need_rehash () khi đăng nhập (và thử lại nếu cần) sẽ đảm bảo rằng các giá trị băm của bạn có khả năng phục hồi hợp lý đối với các cuộc tấn công vũ phu mà không có tác dụng gì với bạn.

EDIT: Tôi chỉ nhận ra rằng điều này được đề cập ngắn gọn trong câu trả lời của Robert K. Tôi sẽ để lại câu trả lời này vì tôi nghĩ nó cung cấp thêm một chút thông tin về cách thức hoạt động và tính dễ sử dụng mà nó cung cấp cho những người không biết bảo mật.


19

Tôi đang sử dụng Phpass , một lớp PHP một tệp đơn giản có thể được triển khai rất dễ dàng trong gần như mọi dự án PHP. Xem thêm H .

Theo mặc định, nó đã sử dụng mã hóa mạnh nhất hiện có được triển khai trong Phpass, bcryptvà quay lại các mã hóa khác xuống MD5 để cung cấp khả năng tương thích ngược với các khung như Wordpress.

Băm trả về có thể được lưu trữ trong cơ sở dữ liệu. Mẫu sử dụng để tạo hàm băm là:

$t_hasher = new PasswordHash(8, FALSE);
$hash = $t_hasher->HashPassword($password);

Để xác minh mật khẩu, người ta có thể sử dụng:

$t_hasher = new PasswordHash(8, FALSE);
$check = $t_hasher->CheckPassword($password, $hash);

14

NHỮNG ĐIỀU CẦN NHỚ

Rất nhiều điều đã được nói về mã hóa Mật khẩu cho PHP, hầu hết đó là lời khuyên rất tốt, nhưng trước khi bạn bắt đầu quá trình sử dụng PHP để mã hóa mật khẩu, hãy đảm bảo rằng bạn đã thực hiện hoặc sẵn sàng thực hiện như sau.

NGƯỜI PHỤC VỤ

PORTS

Cho dù mã hóa của bạn tốt đến đâu nếu bạn không bảo mật đúng cách máy chủ chạy PHP và DB thì mọi nỗ lực của bạn đều vô ích. Hầu hết các máy chủ hoạt động tương đối giống nhau, chúng có các cổng được gán để cho phép bạn truy cập chúng từ xa thông qua ftp hoặc shell. Đảm bảo rằng bạn thay đổi cổng mặc định có kết nối từ xa mà bạn đã kích hoạt. Bằng cách không làm điều này, bạn có hiệu lực đã khiến kẻ tấn công thực hiện một bước ít hơn trong việc truy cập hệ thống của bạn.

TÊN TÀI KHOẢN

Đối với tất cả những gì tốt trên thế giới, không sử dụng quản trị viên tên người dùng, root hoặc một cái gì đó tương tự. Ngoài ra, nếu bạn đang sử dụng hệ thống dựa trên unix, KHÔNG thể truy cập tài khoản root, nó sẽ luôn luôn chỉ sudo.

MẬT KHẨU

Bạn bảo người dùng của bạn tạo mật khẩu tốt để tránh bị hack, hãy làm tương tự. Điểm quan trọng trong việc vượt qua tất cả nỗ lực khóa cửa trước của bạn là gì khi bạn mở cửa sau.

CƠ SỞ

NGƯỜI PHỤC VỤ

Lý tưởng nhất là bạn muốn DB và ỨNG DỤNG của mình trên các máy chủ riêng biệt. Điều này không phải lúc nào cũng có thể do chi phí, nhưng nó cho phép một số an toàn vì kẻ tấn công sẽ phải trải qua hai bước để truy cập đầy đủ vào hệ thống.

NGƯỜI DÙNG

Luôn có ứng dụng của bạn có tài khoản riêng để truy cập DB và chỉ cung cấp cho nó những đặc quyền cần thiết.

Sau đó, có một tài khoản người dùng riêng cho bạn mà không được lưu trữ ở bất kỳ đâu trên máy chủ, thậm chí không có trong ứng dụng.

Giống như luôn luôn KHÔNG làm cho gốc này hoặc một cái gì đó tương tự.

MẬT KHẨU

Thực hiện theo các hướng dẫn tương tự như với tất cả các mật khẩu tốt. Đồng thời không sử dụng lại cùng một mật khẩu trên bất kỳ tài khoản SERVER hoặc DB nào trên cùng một hệ thống.

PHP

MẬT KHẨU

KHÔNG BAO GIỜ lưu trữ mật khẩu trong DB của bạn, thay vào đó lưu trữ hàm băm và muối duy nhất, tôi sẽ giải thích lý do tại sao sau này.

GIÀY

MỘT CÁCH BẮT ĐẦU !!!!!!!, Không bao giờ băm mật khẩu theo cách có thể đảo ngược, Băm nên là một cách, có nghĩa là bạn không đảo ngược chúng và so sánh chúng với mật khẩu, thay vào đó bạn băm mật khẩu đã nhập cùng một cách và so sánh hai băm. Điều này có nghĩa là ngay cả khi kẻ tấn công có quyền truy cập vào DB, anh ta cũng không biết mật khẩu thực sự là gì, chỉ là kết quả băm của nó. Điều đó có nghĩa là bảo mật hơn cho người dùng của bạn trong trường hợp xấu nhất có thể.

Có rất nhiều hàm băm tốt ngoài kia ( password_hash, hashv.v ...) nhưng bạn cần chọn một thuật toán tốt để hàm băm có hiệu quả. (bcrypt và những cái tương tự như nó là các thuật toán phong nha.)

Khi tốc độ băm là chìa khóa, càng chậm khả năng chống lại các cuộc tấn công của Brute Force.

Một trong những lỗi phổ biến nhất trong băm là băm không phải là duy nhất cho người dùng. Điều này chủ yếu là do muối không được tạo ra duy nhất.

BÁN HÀNG

Mật khẩu phải luôn luôn được muối trước khi băm. Salting thêm một chuỗi ngẫu nhiên vào mật khẩu để mật khẩu tương tự không xuất hiện giống nhau trong DB. Tuy nhiên, nếu muối không phải là duy nhất cho mỗi người dùng (ví dụ: bạn sử dụng một loại muối được mã hóa cứng) thì bạn đã làm cho muối của mình trở nên vô dụng. Bởi vì một khi kẻ tấn công tìm ra một mật khẩu muối, anh ta có muối cho tất cả chúng.

Khi bạn tạo một muối, hãy chắc chắn rằng nó là duy nhất với mật khẩu đó là muối, sau đó lưu trữ cả hàm băm và muối đã hoàn thành trong DB của bạn. Điều này sẽ làm là làm cho nó để kẻ tấn công sẽ phải bẻ khóa từng muối và băm trước khi chúng có thể truy cập. Điều này có nghĩa là nhiều công việc và thời gian hơn cho kẻ tấn công.

NGƯỜI DÙNG TẠO PASSWORDS

Nếu người dùng đang tạo mật khẩu thông qua frontend có nghĩa là nó phải được gửi đến máy chủ. Điều này mở ra một vấn đề bảo mật bởi vì điều đó có nghĩa là mật khẩu không được mã hóa đang được gửi đến máy chủ và nếu kẻ tấn công có thể lắng nghe và truy cập thì tất cả bảo mật của bạn trong PHP là vô giá trị. LUÔN LUÔN truyền dữ liệu BẢO MẬT, điều này được thực hiện thông qua SSL, nhưng mệt mỏi ngay cả SSL không hoàn hảo (lỗ hổng Heartbleed của OpenSSL là một ví dụ về điều này).

Cũng làm cho người dùng tạo một mật khẩu an toàn, nó đơn giản và phải luôn luôn được thực hiện, người dùng sẽ biết ơn nó cuối cùng.

Cuối cùng, bất kể các biện pháp bảo mật mà bạn thực hiện không có gì là an toàn 100%, công nghệ bảo vệ càng tiên tiến càng trở nên tiên tiến hơn. Nhưng làm theo các bước này sẽ làm cho trang web của bạn an toàn hơn và ít mong muốn hơn cho những kẻ tấn công đi sau.

Đây là một lớp PHP tạo ra hàm băm và muối cho mật khẩu một cách dễ dàng

http://git.io/mSJqpw


1
Bạn nên tấn công SHA512 từ danh sách các thuật toán băm khá, bởi vì nó quá nhanh. Chỉ sử dụng kết hợp với PBKDF2. Trong khi BCrypt dựa trên blowfish, bản thân blowfish là một thuật toán để mã hóa, không phải để băm.
martinstoeckli

1
Làm thế nào để bạn lưu trữ muối ngẫu nhiên trong DB? Tôi nghĩ rằng bạn không băm nó (không thể được sử dụng để xác minh) cũng như không lưu trữ rõ ràng (không có lợi ích thực sự nếu kẻ tấn công có thể đọc DB). Vì vậy, làm thế nào bạn làm điều đó?
Iazel

wmfrancia đã viết: "Salting thêm một chuỗi ngẫu nhiên vào mật khẩu để mật khẩu tương tự không xuất hiện giống nhau trong DB". Điều này không có ý nghĩa với tôi. Băm trong DB sẽ xuất hiện không giống nhau vì đó là thuộc tính của hàm băm.
H2ONaCl

wmfancia đã viết liên quan đến một loại muối không đổi: "một khi kẻ tấn công tìm ra một loại muối mật khẩu, anh ta có muối cho tất cả chúng". Điều tương tự cũng có thể nói rằng nếu tin tặc tìm ra trường DB nào là muối, anh ta có muối cho tất cả chúng. Vì một loại muối không đổi có lẽ sẽ không có trong DB, đó là một điều tốt về một loại muối không đổi.
H2ONaCl

Tất nhiên, những bình luận này không đề xuất một loại muối ngẫu nhiên cho mỗi người dùng không tốt hơn một muối cho mỗi ứng dụng. Tốt hơn là.
H2ONaCl

12

Google cho biết SHA256 có sẵn cho PHP.

Bạn chắc chắn nên sử dụng một loại muối. Tôi khuyên bạn nên sử dụng các byte ngẫu nhiên (và không giới hạn bản thân ở các ký tự và số). Như thường lệ, bạn chọn càng lâu, càng an toàn, càng chậm. 64 byte nên ổn, tôi đoán vậy.


13
64 bit nên là đủ cho bất cứ ai?
Konerak

@Konerak, tôi sẽ quay lại vấn đề này sau 20 năm. :) Nhưng yep SHA256 thực sự có sẵn. Nếu bạn muốn biết SHA256 an toàn đến mức nào, bạn có thể muốn kiểm tra điều này: security.stackexchange.com/questions/90064/
Kẻ

8

Cuối cùng, băm kép, về mặt toán học, không mang lại lợi ích gì. Tuy nhiên, trên thực tế, nó rất hữu ích để ngăn chặn các cuộc tấn công dựa trên bảng cầu vồng. Nói cách khác, nó không có ích lợi gì hơn việc băm bằng muối, việc này tốn ít thời gian xử lý hơn trong ứng dụng hoặc trên máy chủ của bạn.


2
băm nhiều cũng bảo vệ chống lại các cuộc tấn công từ điển và vũ phu - tức là nó đơn giản làm cho chúng mất nhiều thời gian hơn để tính toán.
frankodwyer

6
băm kép sẽ không cung cấp cho bạn một lợi thế đáng kể nhưng lặp lại băm nhiều vòng vẫn là một biện pháp phòng thủ khả thi chống lại các cuộc tấn công từ điển và lực lượng. Băm mật khẩu cường độ công nghiệp sử dụng hơn 1000 vòng. PBKDF1 của PKCS # 5 gợi ý tối thiểu 1000 vòng.
Berk D. Demir

8

Tôi tìm thấy chủ đề hoàn hảo về vấn đề này ở đây: https://crackstation.net/hashing-security.htmlm , tôi muốn bạn nhận được lợi ích từ nó, đây là mã nguồn cũng cung cấp phòng chống tấn công dựa trên thời gian.

<?php
/*
 * Password hashing with PBKDF2.
 * Author: havoc AT defuse.ca
 * www: https://defuse.ca/php-pbkdf2.htm
 */

// These constants may be changed without breaking existing hashes.
define("PBKDF2_HASH_ALGORITHM", "sha256");
define("PBKDF2_ITERATIONS", 1000);
define("PBKDF2_SALT_BYTES", 24);
define("PBKDF2_HASH_BYTES", 24);

define("HASH_SECTIONS", 4);
define("HASH_ALGORITHM_INDEX", 0);
define("HASH_ITERATION_INDEX", 1);
define("HASH_SALT_INDEX", 2);
define("HASH_PBKDF2_INDEX", 3);

function create_hash($password)
{
    // format: algorithm:iterations:salt:hash
    $salt = base64_encode(mcrypt_create_iv(PBKDF2_SALT_BYTES, MCRYPT_DEV_URANDOM));
    return PBKDF2_HASH_ALGORITHM . ":" . PBKDF2_ITERATIONS . ":" .  $salt . ":" . 
        base64_encode(pbkdf2(
            PBKDF2_HASH_ALGORITHM,
            $password,
            $salt,
            PBKDF2_ITERATIONS,
            PBKDF2_HASH_BYTES,
            true
        ));
}

function validate_password($password, $good_hash)
{
    $params = explode(":", $good_hash);
    if(count($params) < HASH_SECTIONS)
       return false; 
    $pbkdf2 = base64_decode($params[HASH_PBKDF2_INDEX]);
    return slow_equals(
        $pbkdf2,
        pbkdf2(
            $params[HASH_ALGORITHM_INDEX],
            $password,
            $params[HASH_SALT_INDEX],
            (int)$params[HASH_ITERATION_INDEX],
            strlen($pbkdf2),
            true
        )
    );
}

// Compares two strings $a and $b in length-constant time.
function slow_equals($a, $b)
{
    $diff = strlen($a) ^ strlen($b);
    for($i = 0; $i < strlen($a) && $i < strlen($b); $i++)
    {
        $diff |= ord($a[$i]) ^ ord($b[$i]);
    }
    return $diff === 0; 
}

/*
 * PBKDF2 key derivation function as defined by RSA's PKCS #5: https://www.ietf.org/rfc/rfc2898.txt
 * $algorithm - The hash algorithm to use. Recommended: SHA256
 * $password - The password.
 * $salt - A salt that is unique to the password.
 * $count - Iteration count. Higher is better, but slower. Recommended: At least 1000.
 * $key_length - The length of the derived key in bytes.
 * $raw_output - If true, the key is returned in raw binary format. Hex encoded otherwise.
 * Returns: A $key_length-byte key derived from the password and salt.
 *
 * Test vectors can be found here: https://www.ietf.org/rfc/rfc6070.txt
 *
 * This implementation of PBKDF2 was originally created by https://defuse.ca
 * With improvements by http://www.variations-of-shadow.com
 */
function pbkdf2($algorithm, $password, $salt, $count, $key_length, $raw_output = false)
{
    $algorithm = strtolower($algorithm);
    if(!in_array($algorithm, hash_algos(), true))
        die('PBKDF2 ERROR: Invalid hash algorithm.');
    if($count <= 0 || $key_length <= 0)
        die('PBKDF2 ERROR: Invalid parameters.');

    $hash_length = strlen(hash($algorithm, "", true));
    $block_count = ceil($key_length / $hash_length);

    $output = "";
    for($i = 1; $i <= $block_count; $i++) {
        // $i encoded as 4 bytes, big endian.
        $last = $salt . pack("N", $i);
        // first iteration
        $last = $xorsum = hash_hmac($algorithm, $last, $password, true);
        // perform the other $count - 1 iterations
        for ($j = 1; $j < $count; $j++) {
            $xorsum ^= ($last = hash_hmac($algorithm, $last, $password, true));
        }
        $output .= $xorsum;
    }

    if($raw_output)
        return substr($output, 0, $key_length);
    else
        return bin2hex(substr($output, 0, $key_length));
}
?>

Bạn cung cấp cho chúng tôi giải pháp mà không sử dụng không sử dụng
Michael

6

Tôi thường sử dụng SHA1 và muối với ID người dùng (hoặc một số thông tin cụ thể của người dùng khác) và đôi khi tôi cũng sử dụng muối không đổi (vì vậy tôi có 2 phần muối).

SHA1 hiện cũng được coi là có phần bị xâm phạm, nhưng ở mức độ thấp hơn nhiều so với MD5. Bằng cách sử dụng một loại muối (bất kỳ loại muối nào), bạn sẽ ngăn chặn việc sử dụng bảng cầu vồng chung để tấn công băm của bạn (một số người thậm chí đã thành công khi sử dụng Google như một loại bảng cầu vồng bằng cách tìm kiếm hàm băm). Kẻ tấn công có thể tạo ra một bảng cầu vồng bằng cách sử dụng muối của bạn, vì vậy đó là lý do tại sao bạn nên bao gồm một loại muối dành riêng cho người dùng. Bằng cách đó, họ sẽ phải tạo một bảng cầu vồng cho mỗi và mọi bản ghi trong hệ thống của bạn, không chỉ một bảng cho toàn bộ hệ thống của bạn! Với loại muối đó, ngay cả MD5 cũng an toàn.


2
muối không đổi không phải là một ý tưởng tuyệt vời ... có lẽ không phải là một lỗ hổng chết người nhưng nó làm suy yếu một cách không cần thiết chương trình này.
frankodwyer

MD5 và SHA1 rất nhanh, vì vậy đây là một diea xấu.
CodeInChaos

4

SHA1 và một loại muối nên đủ (tùy thuộc vào việc bạn đang mã hóa thứ gì đó cho Fort Knox hoặc hệ thống đăng nhập cho danh sách mua sắm của bạn) trong tương lai gần. Nếu SHA1 không đủ tốt cho bạn, hãy sử dụng SHA256 .

Ý tưởng của một muối là để ném kết quả băm mất cân bằng, có thể nói như vậy. Được biết, ví dụ, hàm băm MD5 của một chuỗi rỗng là d41d8cd98f00b204e9800998ecf8427e. Vì vậy, nếu ai đó có đủ bộ nhớ sẽ thấy hàm băm đó và biết rằng đó là hàm băm của một chuỗi rỗng. Nhưng nếu chuỗi được muối (giả sử với chuỗi " MY_PERSONAL_SALT"), hàm băm cho 'chuỗi rỗng' (nghĩa là " MY_PERSONAL_SALT") trở thành aeac2612626724592271634fb14d3ea6, do đó không rõ ràng đối với backtrace. Những gì tôi đang cố gắng nói, tốt hơn là sử dụng bất kỳ loại muối nào , hơn là không. Do đó, không quá quan trọng để biết nên sử dụng loại muối nào.

Thực tế, có những trang web thực hiện điều này - bạn có thể cung cấp cho nó một hàm băm (md5) và nó tạo ra một bản rõ đã biết tạo ra hàm băm cụ thể đó. Nếu bạn có quyền truy cập vào cơ sở dữ liệu lưu trữ băm md5 đơn giản, việc bạn nhập hàm băm cho quản trị viên vào một dịch vụ đó là chuyện nhỏ và đăng nhập. Nhưng, nếu mật khẩu được xử lý, dịch vụ đó sẽ trở thành không hiệu quả

Ngoài ra, băm kép thường được coi là phương pháp xấu, vì nó làm giảm không gian kết quả. Tất cả các băm phổ biến là chiều dài cố định. Do đó, bạn chỉ có thể có một giá trị hữu hạn có độ dài cố định này và kết quả trở nên ít thay đổi hơn. Đây có thể được coi là một hình thức muối khác, nhưng tôi không khuyến khích điều đó.


Trang web mục tiêu không nên chứa bất cứ thứ gì quá nhạy cảm (nó không phải là ngân hàng), nhưng tôi vẫn muốn bảo mật nó.
luiscubal

1
băm kép không làm giảm không gian kết quả. băm lặp là một điều khiển phổ biến chống lại các cuộc tấn công từ điển và vũ phu (nó làm chậm chúng nhiều hơn là làm chậm việc kiểm tra mật khẩu của bạn).
frankodwyer

2
@frankodwyer: vâng, nó rất tệ. sha1(sha1($foo))có hiệu quả làm giảm không gian đầu ra, bởi vì bất kỳ va chạm nào của chức năng bên trong sẽ tự động trở thành xung đột của bên ngoài. Sự xuống cấp là tuyến tính, nhưng nó vẫn là một mối quan tâm. Các phương pháp băm lặp lại đưa dữ liệu trở lại vào mỗi vòng, chẳng hạn như $hash = sha1(sha1($salt . $password) . $salt). Nhưng điều đó vẫn không tốt ... Hãy gắn bó với PBKDF2 hoặc Bcrypt ...
ircmaxell

-7

ok trong phù hợp chúng ta cần muối muối phải là duy nhất vì vậy hãy tạo ra nó

   /**
     * Generating string
     * @param $size
     * @return string
     */
    function Uniwur_string($size){
        $text = md5(uniqid(rand(), TRUE));
        RETURN substr($text, 0, $size);
    }

Ngoài ra, chúng tôi cần băm tôi đang sử dụng sha512, nó là tốt nhất và nó là trong php

   /**
     * Hashing string
     * @param $string
     * @return string
     */
    function hash($string){
        return hash('sha512', $string);
    }

vì vậy bây giờ chúng ta có thể sử dụng chức năng này để tạo mật khẩu an toàn

// generating unique password
$password = Uniwur_string(20); // or you can add manual password
// generating 32 character salt
$salt = Uniwur_string(32);
// now we can manipulate this informations

// hashin salt for safe
$hash_salt = hash($salt);
// hashing password
$hash_psw = hash($password.$hash_salt);

bây giờ chúng ta cần lưu trong cơ sở dữ liệu giá trị biến $ hash_psw và biến muối $

và để ủy quyền, chúng tôi sẽ sử dụng các bước tương tự ...

đó là cách tốt nhất để bảo mật mật khẩu của khách hàng ...

Ps cho 2 bước cuối cùng bạn có thể sử dụng thuật toán của riêng mình ... nhưng hãy chắc chắn rằng bạn có thể tạo mật khẩu băm này trong tương lai khi bạn cần ủy quyền cho người dùng ...


4
Câu hỏi này là về băm cho mật khẩu. 1 thực thi sha512(ngay cả khi được muối) được coi là không đủ tốt để bảo vệ mật khẩu. (cũng là RNG không bảo mật bằng mật mã, vì vậy sử dụng nó để tạo mật khẩu là rủi ro).
luiscubal

2
Bạn không biết bạn đang làm gì. Đọc các câu trả lời hàng đầu trong bài đăng này và bạn có thể thấy tại sao mã của bạn không chỉ không an toàn mà còn vô nghĩa.
ツkhó hiểu

đồng ý. mã của tôi không an toàn. vậy hãy cho tôi biết lý do tại sao bạn sử dụng thuật toán của mình trên sha256 ??? Tôi biết rằng sha512 là tốt nhất tại sao không sử dụng nó ???
shalvasoft

1
@shalvasoft sha512 khá tốt cho băm mục đích chung, nhưng bảo vệ mật khẩu yêu cầu băm với các thuộc tính rất cụ thể ( ví dụ: "chậm" là một điều tốt , và sha512 khá nhanh). Một số người đã sử dụng sha512 như một khối xây dựng để tạo các hàm băm mật khẩu, nhưng ngày nay phương pháp được đề xuất là "sử dụng bcrypt và để mắt đến tiền điện tử".
luiscubal
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.