2009-06-28 73 views
362

tôi đang làm việc trên một dự án mà phải có chứng thực (tên user/pass)Cách tốt nhất để lưu trữ mật khẩu trong cơ sở dữ liệu

Nó cũng kết nối với một cơ sở dữ liệu vì vậy tôi đoán tôi sẽ lưu trữ tên người dùng và mật khẩu đó nhưng 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 ngồi trên db

Tôi đang sử dụng C# và kết nối với máy chủ tốc hành 2008. bất cứ ai 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 là gì?

(i am mở với ý tưởng rằng thông tin này không được lưu trữ trong db nếu một lý do chính đáng có thể được cung cấp)

+1

Bất kể bạn làm gì, nếu bạn sử dụng mã hóa, không lưu khóa trong mã như một áp phích trước được đề cập. Đó chỉ là thực hành kém. – Woody

+5

'Cách thực hiện 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à những 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 http://programmers.stackexchange.com –

+1

Tốt hơn là nên tuân theo các tiêu chuẩn - xem http://en.wikipedia.org/wiki/PBKDF2 Bạn chỉ phải tìm cách triển khai trong ngôn ngữ –

Trả lời

329

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

Để Clari fy thêm một chút về bit salting, nguy hiểm chỉ đơn giản là băm mật khẩu và lưu trữ đó là nếu kẻ xâm nhập chiế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à rainbow tables để có thể "giải mã" mật khẩu (ít nhất là những người xuất hiện trong bảng cầu vồng). Để giải quyết vấn đề này, các nhà phát triển thêm salt 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ủa cầu vồng không thể thực hiện được. Lưu ý rằng 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 cho tất cả các mật khẩu; trong khi đây không phải là khủng khiếp, tốt nhất là thêm các muối duy nhất vào mọi mật khẩu. Read this for more.

+0

@Paolo Bergantino: "lưu trữ mật khẩu trong cơ sở dữ liệu là điều thích hợp để làm" - Tôi sẽ không đồng ý với tuyên bố đó. –

+31

Tôi có nghĩa là lưu trữ mật khẩu trong cơ sở dữ liệu như trái ngược với lưu trữ nó ở nơi khác. Lấy câu đó ra khỏi bối cảnh làm cho nó 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 tôi rõ ràng là không. –

+0

@Paolo Bergantino: Tôi hiểu ý của bạn là hoàn hảo. Và tôi đã không đưa nó ra khỏi bối cảnh. Thực hành tốt nhất là không lưu trữ ngay cả mật khẩu được mã hóa, nhưng để lưu trữ một băm muối của mật khẩu được mã hóa. –

3

tôi sẽ MD5/SHA1 mật khẩu nếu bạn không cần để có thể đảo ngược 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 mã băm. Hash va chạm là gần như không thể trong trường hợp này, trừ khi ai đó tăng quyền truy cập vào cơ sở dữ liệu và thấy một băm họ đã có một vụ va chạm.

+1

Tôi sẽ không sử dụng MD5 cho băm - về cơ bản nó bị hỏng http : //www.mscs.dal.ca/~selinger/md5collision/ – zebrabox

+2

Thực ra, nó không bị hỏng. Những gì họ có thể làm là tìm giá trị băm giống nhau cho hai tệp khác nhau. Những gì họ không thể làm là đảo ngược MD5 và nhận được một mật khẩu làm việc. – waiwai933

+2

Vâng, không phải lúc đó cũng sẽ bị phá vỡ sao? Bạn chỉ cần nhập mật khẩu khác mà tạo ra cùng một băm, và bạn đang ở. Bạn không cần phải biết mật khẩu ban đầu. Cách khắc phục điều này là nếu bạn nhập mật khẩu trước khi băm. – mjuarez

3

Trong trường hợp của bạn, bạn có thể xem xét tư cách thành viên asp.net, thực tiễn tố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 trữ trong cơ sở dữ liệu.

Tất cả mọi thứ đã được xây dựng cho mục đích này, hãy kiểm tra asp.net membership

31

Là bă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.

+3

Theo tôi, bạn nê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. Việc viết này là một câu trả lời tốt hơn nhiều: https://security.stackexchange.com/questions/211/how-to-securely-hash-passwords. 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

+0

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

25

Thực hành bảo mật tốt nhất là không lưu trữ mật khẩu (không mã hóa), nhưng để 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.

Bằng cách đó (thực tế) không thể truy xuất mật khẩu văn bản thuần túy.

+11

Wayne, bằng cách muối trước khi tính toán băm, bảng cầu vồng bị đánh bại hiệu quả, với điều kiện muối có kích thước đủ. –

+11

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

40

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 người dùng đến biết mật khẩu của tài khoản.

băm: Lưu trữ mật khẩu người dùng được băm (mã hóa một chiều) qua hàm băm mạnh. Tìm kiếm "mật khẩu mã hóa C#" cung cấp một tải ví dụ.

Xem online SHA1 hash creator để biết ý nghĩa của hàm băm (Nhưng không sử dụng hàm SHA1 làm hàm băm, hãy sử dụng hàm 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 được phép đảo ngược mã băm đó trở lại mật khẩu ban đầu.

Cách sử dụng: Tuy nhiên, bạn nói, làm cách nào để sử dụng mật khẩu được nén này được lưu trữ trong cơ sở dữ liệu?

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) Bạn chỉ cần sử dụng cùng mã băm để băm nhập mật khẩu để lấy phiên bản đã lưu trữ.

Vì vậy, hãy so sánh hai mật khẩu được băm (băm cơ sở dữ liệu cho tên người dùng và mật khẩu băm được 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ọ" hay không bằng cách so sánh băm của họ.

tín dụng phụ:

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

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

Vì vậy, bạn nên 'muối' mật khẩu của mình. Xem Wikipedia article on salt

Xem "How to hash data with salt" C# example

+12

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ư gia đình SHA2. –

+3

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

+5

SHA-1 chưa bị hỏng. Nhưng để paraphase Bruce Schneier: Đi bộ, không chạy, để SHA-2. –

6

Tôi có thể hơi lạc đề như bạn đã đề cập đến sự cần thiết của một 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 là admitedly không phải là tốt nhất nhưng là OpenID một cái gì đó đáng giá ?

Nếu bạn sử dụng OpenID thì 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 công nghệ một cách chính xác và người dùng có thể sử dụng thông tin xác thực mà họ đã có, tránh sự cần thiết phải tạo một danh tính mới cụ thể cho ứng dụng của bạn .

Nó có thể không phù hợp nếu ứng dụng trong câu hỏi là hoàn toàn cho sử dụng nội bộ mặc dù

RPX cung cấp một cách thoải mái dễ Tích hợp hỗ trợ OpenID vào một ứng dụng.

+0

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

9

Tôi khuyên bạn nên đọc kỹ các bài viết Enough With The Rainbow Tables: What You Need To Know About Secure Password Schemes [liên kết chết, copy at the Internet Archive] và How To Safely Store A Password.

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

+3

bài viết cung cấp cho một 404. – Johan

+1

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

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