Câu hỏi Làm sạch mật khẩu người dùng


Làm cách nào để thoát hoặc xóa sạch mật khẩu do người dùng cung cấp trước khi tôi băm chúng và lưu trữ chúng trong cơ sở dữ liệu của tôi?

Khi các nhà phát triển PHP xem xét mật khẩu của người dùng băm vì mục đích bảo mật, họ thường có xu hướng nghĩ đến những mật khẩu đó giống như những dữ liệu do người dùng cung cấp khác. Chủ đề này xuất hiện thường xuyên trong các câu hỏi PHP liên quan đến lưu trữ mật khẩu; nhà phát triển thường muốn xóa mật khẩu bằng các chức năng như escape_string()(trong các lần lặp khác nhau), htmlspecialchars(), addslashes() và những người khác trước khi băm và lưu trữ nó trong cơ sở dữ liệu.


76
2018-04-14 16:08


gốc


u có thể mã hóa base64 của người dùng - MSS
Không có @MSS, bạn không nên vì base64 là mã hóa, không phải mã hóa hoặc là băm. Mật khẩu luôn phải là băm nhỏ. - Jay Blanchard
Ý tôi là trước khi băm;) - MSS
Bạn không nên và không cần phải làm điều đó trước khi băm. Nó sẽ khiến bạn phải viết mã bổ sung không cần thiết @MSS - Jay Blanchard


Các câu trả lời:


Bạn không bao giờ nên thoát, cắt hoặc sử dụng bất kỳ cơ chế làm sạch nào khác trên các mật khẩu mà bạn sẽ băm cùng với PHP password_hash() vì một số lý do, một trong những lý do lớn nhất là vì việc làm sạch bổ sung cho mật khẩu yêu cầu mã bổ sung không cần thiết.

Bạn sẽ tranh luận (và bạn nhìn thấy nó trong mỗi bài đăng mà dữ liệu người dùng được chấp nhận để sử dụng trong hệ thống của bạn), chúng ta nên làm sạch tất cả đầu vào của người dùng và bạn sẽ phù hợp với mọi thông tin khác mà chúng tôi chấp nhận từ người dùng của mình. Mật khẩu khác nhau. Mật khẩu bị bẻ khóa không thể cung cấp bất kỳ mối đe dọa tiêm SQL nào vì chuỗi được chuyển thành băm trước khi lưu trữ trong cơ sở dữ liệu.

Hành vi băm mật khẩu là hành động làm cho mật khẩu an toàn để lưu trữ trong cơ sở dữ liệu của bạn. Hàm băm không có ý nghĩa đặc biệt đối với bất kỳ byte nào, vì vậy không cần làm sạch đầu vào của nó vì lý do bảo mật

Nếu bạn theo các câu thần chú cho phép người dùng sử dụng mật khẩu / cụm từ họ mong muốn và bạn không giới hạn mật khẩu, cho phép bất kỳ độ dài nào, bất kỳ số lượng dấu cách nào và bất kỳ ký tự đặc biệt nào sẽ làm cho mật khẩu / cụm mật khẩu an toàn bất kể nội dung nào nằm trong mật khẩu. Hiện tại, băm phổ biến nhất (mặc định), PASSWORD_BCRYPT, biến mật khẩu thành một chuỗi rộng 60 ký tự có chứa một muối ngẫu nhiên cùng với thông tin mật khẩu băm và chi phí (chi phí thuật toán của việc tạo băm):

PASSWORD_BCRYPT được sử dụng để tạo băm mật khẩu mới bằng thuật toán CRYPT_BLOWFISH. Điều này sẽ luôn dẫn đến một băm sử dụng định dạng crypt "$ 2y $", luôn rộng 60 ký tự.

Các yêu cầu về không gian để lưu trữ băm có thể thay đổi khi các phương thức băm khác nhau được thêm vào hàm, vì vậy tốt hơn là nên đi lớn hơn trên loại cột cho băm được lưu trữ, chẳng hạn như VARCHAR(255) hoặc là TEXT.

Bạn có thể sử dụng truy vấn SQL hoàn chỉnh làm mật khẩu của mình và nó sẽ được băm, khiến cho nó không thể thực thi được bằng công cụ SQL, ví dụ:

SELECT * FROM `users`;

Có thể được băm thành $2y$10$1tOKcWUWBW5gBka04tGMO.BH7gs/qjAHZsC5wyG0zmI2C.KgaqU5G

Hãy xem các phương pháp khử trùng khác nhau ảnh hưởng đến mật khẩu như thế nào -

Mật khẩu là I'm a "dessert topping" & a <floor wax>! (Có 5 dấu cách ở cuối mật khẩu không được hiển thị ở đây.)

Khi chúng tôi áp dụng các phương pháp cắt tỉa sau, chúng tôi nhận được một số kết quả khác nhau khác nhau:

var_dump(trim($_POST['upassword']));
var_dump(htmlentities($_POST['upassword']));
var_dump(htmlspecialchars($_POST['upassword']));
var_dump(addslashes($_POST['upassword']));
var_dump(strip_tags($_POST['upassword']));

Các kết quả:

string(40) "I'm a "dessert topping" & a <floor wax>!" // spaces at the end are missing
string(65) "I'm a &quot;dessert topping&quot; &amp; a &lt;floor wax&gt;!     " // double quotes, ampersand and braces have been changed
string(65) "I'm a &quot;dessert topping&quot; &amp; a &lt;floor wax&gt;!     " // same here
string(48) "I\'m a \"dessert topping\" & a <floor wax>!     " // escape characters have been added
string(34) "I'm a "dessert topping" & a !     " // looks like we have something missing

Điều gì sẽ xảy ra khi chúng tôi gửi chúng đến password_hash()? Tất cả chúng đều được băm, giống như truy vấn đã làm ở trên. Sự cố xảy ra khi bạn cố gắng xác minh mật khẩu. Nếu chúng tôi sử dụng một hoặc nhiều phương pháp này, chúng tôi phải tái sử dụng chúng trước khi so sánh chúng với password_verify(). Sau đây sẽ thất bại:

password_verify($_POST['upassword'], $hashed_password); // where $hashed_password comes from a database query

Bạn sẽ phải chạy mật khẩu đã đăng thông qua phương pháp làm sạch mà bạn đã chọn trước khi sử dụng kết quả của việc đó trong xác minh mật khẩu. Đó là một bộ các bước không cần thiết và sẽ làm cho hàm băm không tốt hơn.


Sử dụng phiên bản PHP dưới 5.5? Bạn có thể dùng password_hash()  gói tương thích.

Bạn thực sự không nên sử dụng Mật khẩu MD5 băm.


88
2018-04-14 16:08



Không. Nếu anh ta tạo mật khẩu của mình với dấu cách, được cho phép, anh ta phải sử dụng chúng khi đăng nhập @DanBracuk - Jay Blanchard
Làm thế nào để @DanBracuk? Nếu chúng tôi cho phép người dùng thiết lập mật khẩu mà anh ta mong muốn, bao gồm cả khoảng cách đầu / cuối? - Jay Blanchard
Đó là lý do tại sao hầu hết mọi thứ yêu cầu bạn nhập mật khẩu đã chọn của bạn hai lần. Nếu người dùng thêm vào các không gian trên tai nạn họ sẽ tìm ra trước khi tiếp tục. Nếu người dùng đã làm nó với mục đích hơn là nó không phải là vấn đề. - Occam's Razor
@MargaretBloom, một quy tắc của ngón tay cái chỉ là một heuristic. Đôi khi chúng tôi vẫn cần suy nghĩ kỹ lưỡng, như mật khẩu. Bạn nói "không ai biết mọi thứ sẽ thay đổi như thế nào trong tương lai", nhưng có vẻ như mọi thứ sẽ thay đổi đó là cách chúng ta thoát dữ liệu trước khi chúng ta đưa dữ liệu vào cơ sở dữ liệu, trong trường hợp đó người dùng sẽ thấy mình bị khóa khi mật khẩu của họ không còn khớp với những gì chúng tôi đã lưu trữ. Mối nguy hiểm trong việc không thoát khỏi băm mật khẩu so với nguy cơ trốn thoát chúng là gì? - DavidS
Chính xác: bạn sẽ dĩ nhiên "thoát khỏi băm" theo nghĩa hạn chế của việc chuyển nó một cách chính xác tới một truy vấn SQL được tham số hóa, trong đó một số mã trong trình kết nối SQL của bạn có thể hoặc không thể làm bất cứ điều gì tương ứng với "thoát", bạn không ' Tôi biết và không quan tâm. Bạn sẽ không phải viết bất kỳ mã cụ thể nào để đạt được điều đó, bởi vì nó hoàn toàn thường xuyên cho tất cả các truy vấn SQL của bạn trừ khi trước đó bạn đã đưa ra một số quyết định về cuộc sống nghèo nàn. - Steve Jessop


Trước khi băm mật khẩu, bạn nên bình thường hóa nó như mô tả trong phần 4 của RFC 7613. Đặc biệt:

  1. Quy tắc ánh xạ bổ sung: Mọi trường hợp không gian ASCII phải là      ánh xạ tới không gian ASCII (U + 0020); một không gian ASCII là bất kỳ Unicode nào      điểm mã có một danh mục chung chung của "Z" (với      ngoại trừ U + 0020).

và:

  1. Quy tắc chuẩn hóa: Dạng chuẩn hóa Unicode C (NFC) PHẢI là      áp dụng cho tất cả các ký tự.

Điều này cố gắng đảm bảo rằng nếu người dùng nhập cùng một mật khẩu nhưng sử dụng phương thức nhập khác, mật khẩu vẫn nên được chấp nhận.


31
2018-04-14 16:20



@DavidS, Một cuốn sách Bắc Mỹ Mac siêu sáng bóng (mà Joe đã sử dụng ngay trước khi rời đi) và một máy tính quán cà phê internet quốc tế kém chất lượng của Đài Loan (mà Joe đang cố gắng sử dụng để tải xuống là thẻ lên máy bay). - Margaret Bloom
Âm thanh jingoistic. :-) Cảm ơn mặc dù. - DavidS
Hmm. Nếu bạn làm điều này, thì bạn cũng nên xác thực mật khẩu để từ chối bất kỳ mật khẩu nào chứa ký tự chưa được gán. Nó sẽ là khủng khiếp nếu người dùng sử dụng NEWFANGLED SPACE, ứng dụng của bạn không nhận ra và do đó băm, và sau đó bạn nâng cấp Cơ sở dữ liệu ký tự Unicode và đột nhiên NEWFANGLED SPACE được ánh xạ tới SPACE trước khi băm, như vậy không còn có thể nhập mật khẩu mà ứng dụng của bạn sẽ băm vào băm cũ. - ruakh
@JayBlanchard Bởi vì khi bạn nhấn một thanh dấu cách trên một máy và khi bạn nhấn vào một máy khác, bạn có thể nhận được hai điểm mã Unicode khác nhau và chúng sẽ có hai mã UTF-8 khác nhau, mà người dùng không biết gì cả. Có thể lập luận rằng đây là một vấn đề mà bạn muốn bỏ qua, nhưng RFC 7613 đã được sinh ra từ những vấn đề thực tế như vậy, nó không phải là một khuyến nghị làm việc. - Kuba Ober
@ruakh Khi bạn quyết định xử lý mật khẩu theo một cách nhất định, chúng phải được xử lý theo cách đó, nếu không mọi thứ sẽ bị phá vỡ đối với các trường hợp sử dụng hiện tại. Nếu bạn có ý định thay đổi phương pháp tiền xử lý trong tương lai, bạn nên lưu trữ nó cùng với biểu diễn đã được xử lý trước và được băm của mật khẩu. Bằng cách đó, một khi bạn nhận được đầu vào, bạn chọn phương pháp tiền xử lý / băm dựa trên những gì bạn đang so sánh. - Kuba Ober