Tôi nhận thấy rằng hầu hết các trang web đều gửi mật khẩu dưới dạng văn bản thuần túy qua HTTPS đến máy chủ. Có lợi thế nào không nếu thay vì tôi gửi mã băm của mật khẩu đến máy chủ? Nó sẽ an toàn hơn?
Tôi nhận thấy rằng hầu hết các trang web đều gửi mật khẩu dưới dạng văn bản thuần túy qua HTTPS đến máy chủ. Có lợi thế nào không nếu thay vì tôi gửi mã băm của mật khẩu đến máy chủ? Nó sẽ an toàn hơn?
Câu trả lời:
Đây là một câu hỏi cũ, nhưng tôi cảm thấy cần phải đưa ra ý kiến của mình về vấn đề quan trọng này. Có quá nhiều thông tin sai lệch ở đây
OP chưa bao giờ đề cập đến việc gửi mật khẩu rõ ràng qua HTTP - chỉ HTTPS, nhưng nhiều người dường như đang trả lời câu hỏi về việc gửi mật khẩu qua HTTP vì lý do nào đó. Mà nói:
Tôi tin rằng mật khẩu không bao giờ được giữ lại (chứ đừng nói là truyền đi) ở dạng văn bản thuần túy. Điều đó có nghĩa là không được lưu trên đĩa, hoặc thậm chí trong bộ nhớ.
Mọi người trả lời ở đây dường như nghĩ rằng HTTPS là một viên đạn bạc, nhưng thực tế không phải vậy. Tuy nhiên, nó chắc chắn sẽ giúp ích rất nhiều và nên được sử dụng trong bất kỳ phiên xác thực nào.
Thực sự không cần biết mật khẩu gốc là gì. Tất cả những gì được yêu cầu là một cách đáng tin cậy để tạo (và tạo lại một cách đáng tin cậy) "khóa" xác thực dựa trên văn bản gốc do người dùng chọn. Trong một thế giới lý tưởng, văn bản này sẽ ngay lập tức tạo ra một "khóa" bằng cách băm nó bằng cách sử dụng muối không thể đảo ngược. Muối này phải là duy nhất đối với thông tin xác thực người dùng đang được tạo. "Chìa khóa" này sẽ là thứ mà hệ thống của bạn sử dụng làm mật khẩu. Bằng cách này nếu hệ thống của bạn bị xâm phạm trong tương lai, những thông tin đăng nhập này sẽ chỉ hữu ích đối với tổ chức của bạn và không nơi nào khác mà người dùng đã lười biếng và sử dụng cùng một mật khẩu.
Vì vậy, chúng tôi có một chìa khóa. Bây giờ chúng ta cần xóa mọi dấu vết của mật khẩu trên thiết bị khách.
Tiếp theo, chúng tôi cần lấy chìa khóa đó vào hệ thống của bạn. Bạn không bao giờ nên truyền khóa hoặc mật khẩu "trong sáng". Thậm chí không qua HTTPS. HTTPS không phải là không thể xuyên qua. Trên thực tế, nhiều tổ chức có thể trở thành một MITM đáng tin cậy - không phải từ góc độ tấn công, mà là thực hiện kiểm tra lưu lượng để thực hiện các chính sách bảo mật của riêng họ. Điều này làm suy yếu HTTPS và đây không phải là cách duy nhất nó xảy ra (chẳng hạn như chuyển hướng đến các cuộc tấn công HTTP MITM chẳng hạn). Đừng bao giờ cho rằng nó an toàn.
Để giải quyết vấn đề này, chúng tôi băm khóa bằng một lần tắt. Nonce này là duy nhất cho mọi lần gửi khóa vào hệ thống của bạn - ngay cả đối với cùng một thông tin đăng nhập trong cùng một phiên nếu bạn cần gửi nhiều lần. Bạn có thể đảo ngược điều này khi nó đến hệ thống của riêng bạn để khôi phục khóa xác thực và xác thực yêu cầu.
Tại thời điểm này, tôi sẽ không thể đảo ngược băm nó lần cuối trước khi nó được lưu trữ vĩnh viễn trong hệ thống của riêng bạn. Bằng cách đó, bạn có thể chia sẻ muối của thông tin xác thực với các tổ chức đối tác vì mục đích SSO và tương tự, trong khi có thể chứng minh tổ chức của riêng bạn không thể mạo danh người dùng. Phần tốt nhất của phương pháp này là bạn không bao giờ chia sẻ bất kỳ thứ gì do người dùng tạo ra mà không có sự cho phép của họ.
Hãy nghiên cứu thêm, vì còn nhiều điều hơn cả những gì tôi đã tiết lộ, nhưng nếu bạn muốn cung cấp bảo mật thực sự cho người dùng của mình, tôi nghĩ phương pháp này hiện là phản hồi đầy đủ nhất ở đây.
TL; DR:
Sử dụng HTTPS. Mật khẩu băm an toàn, không thể thay đổi, với một muối duy nhất cho mỗi mật khẩu. Thực hiện việc này trên máy khách - không truyền mật khẩu thực của họ. Việc truyền mật khẩu ban đầu của người dùng tới máy chủ của bạn không bao giờ là "OK" hoặc "Fine". Xóa sạch mọi dấu vết của mật khẩu ban đầu. Sử dụng nonce bất kể HTTP / HTTPS. Nó an toàn hơn nhiều ở nhiều cấp độ. (Trả lời OP).
Vì nó qua HTTPS, chắc chắn bạn chỉ cần gửi mật khẩu mà không cần băm (qua HTTPS, nó không phải là văn bản rõ ràng). Hơn nữa, nếu ứng dụng của bạn phụ thuộc vào HTTPS để giữ cho nội dung của nó an toàn, thì việc băm mật khẩu trước khi gửi nó qua HTTPS là vô ích (tức là nếu kẻ tấn công có thể giải mã dữ liệu trên dây, bạn sẽ bị hỏng)
Không, trên thực tế đây sẽ là một lỗ hổng. Nếu kẻ tấn công có thể lấy được băm từ cơ sở dữ liệu, thì anh ta có thể sử dụng nó để xác thực mà không cần bẻ khóa. Trong bất kỳ trường hợp nào, người dùng hoặc kẻ tấn công không thể lấy được mật khẩu băm.
Toàn bộ điểm của mật khẩu băm là thêm một lớp bảo mật bổ sung. Nếu kẻ tấn công có thể lấy băm và muối từ cơ sở dữ liệu bằng cách sử dụng SQL Injection hoặc một bản sao lưu không an toàn thì anh ta phải tìm văn bản thuần túy bằng cách ép buộc nó. John The Ripper thường được sử dụng để phá các hàm băm mật khẩu mặn.
Không sử dụng https là vi phạm OWASP Top 10: Bảo vệ lớp truyền tải không đầy đủ A9
CHỈNH SỬA:
Nếu trong quá trình triển khai, bạn tính toán a sha256(client_salt+plain_text_password)
và sau đó tính toán một hàm băm khác ở phía máy chủ sha256(server_salt+client_hash)
thì đây không phải là một lỗ hổng nghiêm trọng. Tuy nhiên, nó vẫn dễ bị nghe trộm và phát lại yêu cầu. Vì vậy, đây vẫn là một vi phạm rõ ràng của WASP A9. Tuy nhiên, điều này vẫn sử dụng một thông báo thông báo làm lớp bảo mật.
Điều gần nhất mà tôi đã thấy đối với sự thay thế phía máy khách cho https là một diffie-hellman trong trao đổi khóa trong javascript . Tuy nhiên, điều này ngăn chặn các cuộc tấn công MITM đang hoạt động và do đó, cho đến khi tính kỹ thuật vi phạm OWASP A9. Các tác giả của mã đồng ý rằng đây không phải là sự thay thế hoàn toàn cho HTTPS, tuy nhiên nó tốt hơn không có gì và tốt hơn hệ thống băm phía máy khách.
Gửi một mã băm qua dây hoàn toàn đánh bại mục đích của hàm băm, bởi vì kẻ tấn công có thể chỉ cần gửi hàm băm và quên mật khẩu. Tóm lại, một hệ thống xác thực bằng cách sử dụng hàm băm trong văn bản rõ ràng là rất rộng mở và có thể bị xâm phạm mà không có gì khác ngoài việc dò tìm mạng.
Mật khẩu trong văn bản rõ ràng không bao giờ (ngay cả khi sử dụng HTTPS) rời khỏi ứng dụng khách. Nó phải được băm không thể đảo ngược trước khi rời khỏi máy khách vì máy chủ không cần biết mật khẩu thực.
Việc băm sau đó truyền giải quyết các vấn đề bảo mật cho người dùng lười biếng sử dụng cùng một mật khẩu ở nhiều vị trí (tôi biết là tôi có). Tuy nhiên, điều này không bảo vệ ứng dụng của bạn vì một tin tặc đã giành được quyền truy cập vào cơ sở dữ liệu (hoặc theo bất kỳ cách nào khác có thể lấy được hàm băm) vì tin tặc chỉ có thể truyền hàm băm và yêu cầu máy chủ chấp nhận nó.
Để giải quyết vấn đề này, tất nhiên bạn có thể chỉ cần băm băm mà máy chủ nhận được và gọi nó là một ngày.
Cách tiếp cận của tôi đối với vấn đề trong một ứng dụng web dựa trên socket mà tôi đang tạo là khi kết nối với máy khách, máy chủ tạo ra một muối (chuỗi ngẫu nhiên được thêm vào trước khi băm) và lưu trữ nó trên biến sockets, sau đó nó truyền hàm băm này cho khách hàng. Máy khách lấy mật khẩu của người dùng, băm mật khẩu, thêm muối từ máy chủ và băm toàn bộ trước khi truyền đến máy chủ. Sau đó, nó được gửi đến máy chủ so sánh hàm băm này với hàm băm (hàm băm trong DB + muối). Theo như tôi biết thì đây là một cách tiếp cận tốt, nhưng công bằng mà nói, tôi chưa đọc nhiều về chủ đề này và nếu tôi sai về bất cứ điều gì tôi muốn được sửa chữa :)
Sử dụng Thông báo HTTP - nó bảo mật mật khẩu ngay cả qua http (nhưng cách sử dụng tốt nhất sẽ là thông báo http qua https)
Wikipedia:
Xác thực truy cập thông báo HTTP là một trong những phương pháp đã thỏa thuận mà máy chủ web có thể sử dụng để thương lượng thông tin xác thực với người dùng web (sử dụng giao thức HTTP). Xác thực thông số nhằm thay thế việc sử dụng không được mã hóa của Xác thực truy cập cơ bản, cho phép danh tính người dùng được thiết lập một cách an toàn mà không cần phải gửi mật khẩu ở dạng văn bản rõ ràng qua mạng. Xác thực số về cơ bản là một ứng dụng băm mật mã MD5 với việc sử dụng các giá trị nonce để ngăn chặn việc phân tích mật mã.
Liên kết: http://en.wikipedia.org/wiki/Digest_access_authentication
Nếu bạn muốn xem cách sử dụng "ngoài đời thực", bạn có thể xem phpMyID - một nhà cung cấp php openid sử dụng xác thực http thông báo http://siege.org/phpmyid.php
.. hoặc bạn có thể bắt đầu từ các mẫu php auth tại http://php.net/manual/en/features.http-auth.php
Thông báo htp rfc: http://www.faqs.org/rfcs/rfc2617
Từ các thử nghiệm của tôi, tất cả các trình duyệt hiện đại đều hỗ trợ nó ...
Nếu bạn đang tìm cách thay thế mật khẩu văn bản rõ ràng qua HTTPS bằng mật khẩu băm qua HTTP thì bạn đang gặp rắc rối. HTTPS tạo khóa giao dịch được chia sẻ ngẫu nhiên khi mở một kênh giao tiếp. Điều đó rất khó để bẻ khóa, vì bạn bị hạn chế khá nhiều trong việc ép buộc khóa chia sẻ được sử dụng cho một giao dịch (tương đối) ngắn hạn. Trong khi đó, hàm băm của bạn có thể được đánh hơi, đưa ra ngoài luồng và tìm kiếm trong bảng cầu vồng hoặc chỉ bị ép buộc vũ phu trong một khoảng thời gian dài.
Tuy nhiên, mật khẩu cơ bản phía máy khách (không phải băm) được gửi qua HTTPS có một số giá trị. Nếu tôi không nhầm thì kỹ thuật này thực sự được một số ngân hàng sử dụng. Mục đích của kỹ thuật này không phải để bảo vệ mật khẩu khỏi bị đánh cắp qua đường dây. Thay vào đó, nó ngăn mật khẩu có thể sử dụng được đối với các công cụ gián điệp ngu ngốc và các plugin trình duyệt chỉ lấy mọi yêu cầu HTTPS GET / POST mà họ thấy. Tôi đã thấy một tệp nhật ký được ghi lại từ một trang web độc hại có 400MB giao dịch GET / POST ngẫu nhiên được ghi lại từ các phiên người dùng. Bạn có thể tưởng tượng rằng các trang web chỉ sử dụng HTTPS sẽ hiển thị với mật khẩu văn bản rõ ràng trong nhật ký, nhưng các trang web có sự xáo trộn rất cơ bản (ROT13) cũng sẽ hiển thị với mật khẩu không được sử dụng ngay lập tức.
Nếu bạn được kết nối với máy chủ https, luồng dữ liệu giữa máy chủ và trình duyệt sẽ được mã hóa. Dữ liệu chỉ là văn bản thuần túy trước khi được gửi và sau khi được nhận. Bài viết trên Wikipedia
Tuyên bố từ chối trách nhiệm: Tôi hoàn toàn không phải là một chuyên gia bảo mật - và tôi đăng bài với hy vọng rằng những người khác sẽ chỉ trích lập trường của tôi là quá thận trọng hoặc không thể ứng biến và tôi sẽ rút kinh nghiệm. Như đã nói, tôi chỉ muốn nhấn mạnh rằng băm khi nó rời khỏi máy khách của bạn không có nghĩa là bạn không cần phải băm trên phần phụ trợ trước khi đưa nó vào cơ sở dữ liệu.
Làm tất cả
Làm cả hai vì:
Việc băm khi di chuyển giúp che lỗ hổng vận chuyển, nếu kết nối SSL bị xâm phạm, họ vẫn không thể nhìn thấy mật khẩu thô. Việc có thể mạo danh người dùng được ủy quyền sẽ không thành vấn đề, nhưng nó sẽ bảo vệ người dùng của bạn không bị đọc mật khẩu của họ trong liên kết với email của họ. Hầu hết mọi người không tuân theo phương pháp hay nhất và sử dụng cùng một mật khẩu cho nhiều tài khoản của họ, vì vậy đây có thể là một lỗ hổng nghiêm trọng đối với khách truy cập của bạn.
Nếu ai đó, bằng cách nào đó có thể đọc mật khẩu từ cơ sở dữ liệu (điều này xảy ra, hãy nghĩ đến việc đưa vào SQL), họ vẫn sẽ không thể thực hiện các hành động đặc quyền mạo danh người dùng thông qua API của tôi. Điều này là do sự bất đối xứng của hàm băm; ngay cả khi họ biết mã băm được lưu trữ trong DB của bạn, họ sẽ không biết khóa gốc được sử dụng để tạo nó và đó là những gì phần mềm trung gian auth của bạn sử dụng để xác thực. Đây cũng là lý do tại sao bạn nên muối lưu trữ băm của mình.
Đúng là, họ có thể gây ra nhiều thiệt hại khác nếu họ có quyền kiểm soát miễn phí để đọc những gì họ muốn từ cơ sở dữ liệu của bạn.
Tôi chỉ muốn nhấn mạnh ở đây rằng nếu bạn quyết định băm khóa trước khi rời khỏi khách hàng của mình, điều đó là chưa đủ - băm phụ trợ, imo, quan trọng hơn nhiều và đây là lý do tại sao: Nếu ai đó đang chặn lưu lượng truy cập từ khách hàng, sau đó họ sẽ thấy nội dung của password
trường. Cho dù đây là mã băm hay văn bản thuần túy, điều đó không quan trọng - họ có thể sao chép nguyên văn nó để mạo danh khách hàng được ủy quyền. (Trừ khi bạn làm theo các bước mà @ user3299591 nêu ra và tôi khuyên bạn nên làm). Mặt khác, việc băm cột DB là một điều cần thiết và không hề khó thực hiện.
Không phải SSL / TLS thay thế nonce sao? Tôi không thấy giá trị gia tăng của điều này vì SSL / TLS cũng bảo vệ chống lại Các cuộc tấn công phát lại.
Thực sự sẽ kém an toàn hơn nếu băm mật khẩu và gửi nó qua một kênh không được mã hóa. Bạn sẽ hiển thị thuật toán băm của mình trên máy khách. Tin tặc có thể chỉ cần đánh hơi mật khẩu và sau đó sử dụng nó để xâm nhập.
Bằng cách sử dụng HTTPS, bạn ngăn tin tặc lấy được mật khẩu từ một nguồn duy nhất, vì HTTPS sử dụng hai kênh, cả hai đều được mã hóa.
Việc có lợi thế hay không và liệu nó có an toàn hơn (hay ít hơn) thực sự phụ thuộc vào việc triển khai. Có thể nói là có một số lợi thế, nhưng nếu bạn triển khai nó kém, bạn chắc chắn có thể tạo ra một giải pháp kém an toàn hơn so với việc chuyển ngay cả mật khẩu văn bản rõ.
Điều này có thể được xem xét dưới góc độ của hai kiểu tấn công - một kiểu truy cập vào lưu lượng mạng và một kiểu khác truy cập vào cơ sở dữ liệu.
Nếu kẻ tấn công của bạn có thể chặn phiên bản văn bản rõ ràng của lưu lượng truy cập mạng, thì việc xem mã băm của mật khẩu sẽ an toàn hơn so với việc xem mật khẩu ở dạng văn bản rõ. Mặc dù kẻ tấn công vẫn có thể đăng nhập vào máy chủ của bạn bằng cách sử dụng hàm băm đó, nhưng nó sẽ yêu cầu crack brute-force (đôi khi được tính toán trước) của hàm băm đó để xác định mật khẩu có thể hữu ích trên các hệ thống khác. Mọi người nên sử dụng các mật khẩu khác nhau trên các hệ thống khác nhau, nhưng thường thì không.
Nếu kẻ tấn công giành được quyền truy cập vào cơ sở dữ liệu, có thể thông qua một bản sao lưu, thì bạn muốn đảm bảo rằng kẻ đó không thể đăng nhập chỉ với kiến thức đó. Ví dụ: nếu bạn lưu trữ một hàm băm có muối với tên đăng nhập là hash(login_name+password)
và bạn chuyển cùng một hàm băm đó từ máy khách để so sánh trực tiếp, thì kẻ tấn công có thể chọn một người dùng ngẫu nhiên, gửi mã băm đã đọc từ cơ sở dữ liệu và đăng nhập với tư cách người dùng đó mà không biết mật khẩu, làm tăng phạm vi vi phạm. Trong trường hợp đó, việc gửi mật khẩu ở dạng bản rõ sẽ an toàn hơn vì kẻ tấn công sẽ cần biết bản rõ để đăng nhập, thậm chí có một bản sao của cơ sở dữ liệu. Đây là nơi mà việc triển khai là quan trọng. Cho dù bạn gửi mật khẩu văn bản rõ ràng hay băm phía máy khách của mật khẩu đó, bạn nên băm giá trị đó ở phía máy chủ và so sánh băm đó với băm được lưu trữ trong bản ghi người dùng.
Các khái niệm cần ghi nhớ: