Cách tốt nhất để lưu trữ mật khẩu trong cơ sở dữ liệu [đã đóng]


475

Tôi đang làm việc trên một dự án phải có xác thực (tên người dùng và mật khẩu)

Nó cũng kết nối với cơ sở dữ liệu, vì vậy tôi đoán rằng tôi sẽ lưu tên người dùng và mật khẩu ở đó. Tuy nhiên, có vẻ như không phải là một ý tưởng tốt để có mật khẩu chỉ là một trường văn bản trong một bảng nằm trên cơ sở dữ liệu.

Tôi đang sử dụng C # và kết nối với máy chủ chuyển phát nhanh năm 2008. Bất cứ ai cũng có thể đề xuất (với càng nhiều ví dụ càng tốt) cách tốt nhất để lưu trữ loại dữ liệu này sẽ là gì?

PS Tôi mở ra ý tưởng rằng thông tin này không được lưu trữ trong cơ sở dữ liệu nếu một lý do chính đáng có thể được cung cấp


1
Dù bạn làm gì, nếu bạn đi với mã hóa, đừng lưu trữ mã trong mã như một poster trước đó đã đề cập. Đó chỉ là thực hành kém.
Woody

12
'Làm thế nào để làm mật khẩu phải không?' là một câu hỏi quan trọng Đó là một vấn đề khó khăn và sai lầm có hậu quả nghiêm trọng (nhớ lại những gì đã xảy ra với Tesco và LinkedIn). Tôi nghĩ rằng câu hỏi này nên được mở lại tại lập trình viên.stackexchange.com
Đại tá Panic

2
Tốt hơn hết là bạn nên tuân thủ các tiêu chuẩn - xem en.wikipedia.org/wiki/PBKDF2 Bạn chỉ cần tìm một cách thực hiện bằng ngôn ngữ của mình
Boris Treukhov

5
Câu hỏi này được trả lời rộng rãi trong diễn đàn bảo mật
gioele

Câu trả lời:


405

Bạn đúng rằng lưu trữ mật khẩu trong trường văn bản đơn giản là một ý tưởng khủng khiếp . Tuy nhiên, theo như vị trí , đối với hầu hết các trường hợp bạn sẽ gặp phải (và thực sự tôi không thể nghĩ ra bất kỳ ví dụ phản biện nào) lưu trữ việc thể hiện mật khẩu trong cơ sở dữ liệu là điều nên làm. Theo cách trình bày, tôi có nghĩa là bạn muốn băm mật khẩu bằng cách sử dụng muối (nên khác với mọi người dùng) và thuật toán 1 chiều an toàn và lưu trữ mật khẩu đó , vứt bỏ mật khẩu gốc. Sau đó, khi bạn muốn xác minh mật khẩu, bạn băm giá trị (sử dụng cùng thuật toán băm và muối) và so sánh nó với giá trị băm trong cơ sở dữ liệu.

Vì vậy, trong khi đó là một điều tốt mà bạn đang nghĩ về điều này và nó là một câu hỏi hay, đây thực sự là một bản sao của những câu hỏi này (ít nhất):

Để làm rõ hơn một chút về bit salting, điều nguy hiểm chỉ bằng cách băm mật khẩu và lưu trữ đó là nếu người xâm phạm nắm giữ cơ sở dữ liệu của bạn, họ vẫn có thể sử dụng cái được gọi là bảng cầu vồng để có thể "giải mã" mật khẩu (ít nhất là những mật khẩu hiển thị trong bảng cầu vồng). Để giải quyết vấn đề này, các nhà phát triển thêm một loại muối vào mật khẩu, khi được thực hiện đúng cách, làm cho các cuộc tấn công cầu vồng đơn giản là không thể thực hiện được. Xin lưu ý rằng một quan niệm sai lầm phổ biến là chỉ cần thêm cùng một chuỗi dài và duy nhất vào tất cả các mật khẩu; Trong khi điều này không phải là khủng khiếp , tốt nhất là thêm muối duy nhất vào mỗi mật khẩu. Đọc này để biết thêm.


40
Tôi có nghĩa là lưu trữ mật khẩu trong cơ sở dữ liệu trái ngược với việc lưu trữ nó ở nơi khác. Việc đưa câu đó ra khỏi ngữ cảnh có vẻ như tôi đang hỗ trợ lưu trữ mật khẩu đơn giản, nếu bạn đọc phần còn lại thì rõ ràng là tôi không biết.
Paolo Bergantino

14
Không chỉ là những gì tôi nói, tôi đã hướng dẫn anh ấy rất nhiều bài viết thảo luận về muối và hơn thế nữa ...
Paolo Bergantino

1
@Paolo Bergantino: bạn có chắc là không có lỗi đánh máy trong bài viết của mình không? Nó nói "Đối với hầu hết các trường hợp bạn sẽ gặp phải (và thực lòng tôi không thể nghĩ ra bất kỳ ví dụ phản biện nào) lưu trữ mật khẩu trong cơ sở dữ liệu là điều nên làm". ??? Nó dường như phản bác ý kiến ​​của bạn
Mitch Wheat

3
Những gì Paolo nói trực tiếp mâu thuẫn với chính nó. Băm mật khẩu không phải là mật khẩu. Lưu trữ một hàm băm của mật khẩu trong cơ sở dữ liệu không lưu trữ mật khẩu trong cơ sở dữ liệu. Phần thân của câu trả lời là hoàn toàn phù hợp, nhưng câu đầu tiên của nó cực kỳ sai lệch.
Robert Rossney

40
@Robert: Điều đó đang tiến gần đến một trò chơi ngữ nghĩa nhỏ nhặt, nhưng dù sao tôi cũng sẽ sửa nó ...
Paolo Bergantino

54

Bối cảnh Bạn không bao giờ ... thực sự ... cần biết mật khẩu của người dùng. Bạn chỉ muốn xác minh một người dùng đến biết mật khẩu cho một tài khoản.

Hash It: Lưu mật khẩu người dùng được băm (mã hóa một chiều) thông qua chức năng băm mạnh. Tìm kiếm "mật khẩu mã hóa c #" cung cấp vô số ví dụ.

Xem trình tạo hàm băm SHA1 trực tuyến để biết ý tưởng về hàm băm tạo ra (Nhưng đừng sử dụng SHA1 làm hàm băm, hãy sử dụng thứ gì đó mạnh hơn như SHA256).

Bây giờ, mật khẩu băm có nghĩa là bạn (và kẻ trộm cơ sở dữ liệu) không thể đảo ngược hàm băm đó trở lại mật khẩu ban đầu.

Cách sử dụng: Nhưng, bạn nói, làm thế nào để tôi sử dụng mật khẩu đã được lưu trong cơ sở dữ liệu này?

Khi người dùng đăng nhập, họ sẽ đưa cho bạn tên người dùng và mật khẩu (trong văn bản gốc của nó) Bạn chỉ cần sử dụng cùng mã băm để băm mật khẩu đã nhập để có phiên bản được lưu trữ.

Vì vậy, hãy so sánh hai mật khẩu băm (băm cơ sở dữ liệu cho tên người dùng và mật khẩu đã nhập & băm). Bạn có thể biết liệu "những gì họ đã nhập" khớp với "những gì người dùng ban đầu đã nhập cho mật khẩu của họ" bằng cách so sánh các giá trị băm của họ.

Tín dụng thêm:

Câu hỏi: Nếu tôi có cơ sở dữ liệu của bạn, thì tôi không thể lấy một công cụ bẻ khóa như John the Ripper và bắt đầu thực hiện băm cho đến khi tôi tìm thấy kết quả khớp với mật khẩu được băm, lưu trữ của bạn? (vì người dùng chọn các từ ngắn, từ điển dù sao đi nữa ... nó sẽ dễ dàng)

Trả lời: Có ... có họ có thể.

Vì vậy, bạn nên 'muối' mật khẩu của bạn. Xem bài viết Wikipedia về muối

Xem ví dụ "Cách băm dữ liệu bằng muối" C #


14
Bài đăng hay, ngoại trừ một điều: md5 và sha1 đều đã bị hỏng. Bạn có lẽ nên đi với một thuật toán mạnh hơn, chẳng hạn như có thể là gia đình SHA2.
Paolo Bergantino

3
Cảm ơn Paolo - bạn đã đúng. Vì việc sử dụng SHA2 dễ dàng như sử dụng MD5 & SHA1, vui lòng sử dụng thuật toán băm mạnh hơn.
joej

5
SHA-1 chưa bị phá vỡ. Nhưng để diễn giải Bruce Schneier: Đi bộ, đừng chạy, đến SHA-2.
Ian Boyd

2
"Vì vậy, bạn nên 'muối' mật khẩu của mình" ... Nhưng muối thường được lưu trữ trong cơ sở dữ liệu cùng với mật khẩu, vậy điều đó có ích gì? Kẻ tấn công Te chỉ đơn giản là phải thêm muối vào các cụm từ tấn công từ điển mà anh ta đang thử nghiệm. Làm thế nào là an toàn hơn ngoài nó sẽ không tiết lộ mật khẩu trùng lặp?
trusktr

4
@joej "Bạn không bao giờ ... thực sự ... cần biết mật khẩu của người dùng" - đó là một giả định rất thiển cận. Có nhiều loại ứng dụng mà mật khẩu được lưu trữ theo cách có thể được truy xuất là thực sự cần thiết. Ví dụ: một ứng dụng cần thường xuyên đăng nhập vào hệ thống khác với thông tin được lưu trữ, được cung cấp và cập nhật bởi người dùng.
Francisco Zarabozo

29

Là một hàm băm được làm cứng bằng khóa, sử dụng thuật toán bảo mật như sha-512.


6
Theo tôi, bạn nên luôn luôn sử dụng các thuật toán chậm (ví dụ như Blowfish) để lưu trữ mật khẩu. Bài viết này là một câu trả lời tốt hơn nhiều: security.stackexchange.com/questions/211/ . Chỉ cần đặt nó ở đây, bởi vì trang này vẫn xuất hiện cao trong kết quả tìm kiếm.
Dynom

2
Làm theo lời khuyên này để lưu trữ mật khẩu sẽ làm điều đó sai lầm.
mlissner

27

Thực hành bảo mật tốt nhất không phải là lưu trữ mật khẩu (thậm chí không được mã hóa), mà là lưu trữ hàm băm muối (với một muối duy nhất cho mỗi mật khẩu) của mật khẩu được mã hóa.

Theo cách đó, thực tế là không thể lấy lại mật khẩu văn bản gốc.


11
Wayne, bằng cách muối trước khi tính toán hàm băm, bảng cầu vồng bị đánh bại một cách hiệu quả, miễn là muối có kích thước đủ.
Mike Rosenblum

11
@Wayne Hartman: Không phải vậy. Nếu giá trị muối bị lộ, thì bạn phải tạo bảng cầu vồng mới cho giá trị muối cụ thể đó. Điểm của bảng cầu vồng là có các giá trị băm được tính toán trước. Và không ai sẽ có một bàn cầu vồng cho muối cụ thể của mình.
Ian Boyd

10

Tôi hoàn toàn khuyên bạn nên đọc các bài viết Đủ với Bàn Cầu vồng: Những điều bạn cần biết về Lược đồ mật khẩu an toàn [liên kết chết, sao chép tại Lưu trữ Internet ] và Cách lưu trữ mật khẩu an toàn .

Nhiều lập trình viên, bao gồm cả tôi, nghĩ rằng họ hiểu bảo mật và băm. Đáng buồn thay, hầu hết chúng ta không.


1
@Johan Hình như liên kết bây giờ bị hỏng đó là một sự xấu hổ. Đây là một codahale.com/how-to-safely-store-a-password
zebrabox

6

Tôi có thể hơi lạc đề vì bạn đã đề cập đến nhu cầu về tên người dùng và mật khẩu, và sự hiểu biết của tôi về vấn đề này được thừa nhận không phải là tốt nhất nhưng liệu OpenID có gì đáng để xem xét không?

Nếu bạn sử dụng OpenID thì cuối cùng bạn sẽ không lưu trữ bất kỳ thông tin xác thực nào nếu tôi hiểu chính xác công nghệ và người dùng có thể sử dụng thông tin đăng nhập mà họ đã có, tránh việc phải tạo một danh tính mới dành riêng cho ứng dụng của bạn.

Nó có thể không phù hợp nếu ứng dụng được đề cập hoàn toàn cho sử dụng nội bộ

RPX cung cấp một cách dễ dàng dễ dàng để kết hợp hỗ trợ OpenID vào một ứng dụng.


Tôi đồng ý rằng những người đá openID phải đối mặt nhưng với ứng dụng này, đó là cơ sở dữ liệu nội bộ cho một công ty, tôi nghi ngờ họ sẽ muốn bất kỳ người già nào đăng nhập. Ngoài ra, không cần truy cập web để ứng dụng này hoạt động chính xác nên tôi không muốn yêu cầu nó.
Crash893

3

Trong kịch bản của bạn, bạn có thể xem thành viên asp.net, cách tốt nhất là lưu trữ mật khẩu của người dùng dưới dạng chuỗi băm trong cơ sở dữ liệu. bạn có thể xác thực người dùng bằng cách so sánh mật khẩu đến được băm với mật khẩu được lưu trong cơ sở dữ liệu.

Mọi thứ đã được xây dựng cho mục đích này, hãy xem thành viên asp.net


1

Tôi sẽ MD5 / SHA1 mật khẩu nếu bạn không cần phải có thể đảo ngược hàm băm. Khi người dùng đăng nhập, bạn chỉ có thể mã hóa mật khẩu đã cho và so sánh nó với hàm băm. Xung đột băm là gần như không thể trong trường hợp này, trừ khi ai đó có quyền truy cập vào cơ sở dữ liệu và thấy một hàm băm mà họ đã có xung đột.


2
Tôi sẽ không sử dụng MD5 để băm - về cơ bản nó đã bị hỏng mscs.dal.ca/~selinger/md5collision
ngựa vằn

3
Trên thực tế, nó không phải là bị hỏng. Những gì họ có thể làm là tìm cùng một giá trị băm cho hai tệp khác nhau. Những gì họ không thể làm là đảo ngược MD5 và lấy mật khẩu hoạt động.
waiwai933

2
Chà, điều đó cũng sẽ bị phá vỡ chứ? Bạn chỉ cần nhập mật khẩu khác tạo cùng hàm băm và bạn vào. Bạn không cần biết mật khẩu gốc. Cách khắc phục là nếu bạn muối mật khẩu trước khi băm.
mjuarez

2
@mjuarez nếu bạn thêm muối vào mật khẩu cho dù bạn sử dụng MD5 thì sự va chạm không thành vấn đề vì bạn không thể sử dụng mật khẩu khác
WiiMaxx
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.