2009-03-05 42 views
75

Phương thức/kiểu dữ liệu ưa thích của bạn để lưu trữ mật khẩu trong cơ sở dữ liệu (tốt nhất là SQL Server 2005). Cách tôi đã làm nó trong một số ứng dụng của chúng tôi là lần đầu tiên sử dụng các thư viện mã hóa .NET và sau đó lưu trữ chúng trong cơ sở dữ liệu dưới dạng nhị phân (16). Đây có phải là phương pháp ưa thích hay tôi nên sử dụng một kiểu dữ liệu khác hoặc phân bổ nhiều không gian hơn 16?Phương thức lưu trữ mật khẩu ưa thích trong cơ sở dữ liệu

+1

Tôi có một cảm giác này có thể là một dupe nhưng những gì tôi nghĩ có thể là một dupe của nó hóa ra là liên quan đến việc đăng nhập DB thực tế và không chỉ lưu trữ ứng dụng/trang web đăng nhập. – TheTXI

+1

Bạn có thể làm rõ câu hỏi của mình để giải thích cho dù bạn đang sử dụng các chức năng "mã hóa" hay "băm"? Tôi nghĩ rằng bạn có nghĩa là sau này, nhưng sự khác biệt là rất đáng kể. – ine

Trả lời

80

tôi lưu trữ băm ướp muối tương đương với mật khẩu trong cơ sở dữ liệu và không bao giờ mật khẩu riêng của mình, sau đó luôn luôn so sánh băm để được tạo ra một trong những gì người dùng thông qua vào.

Đó là quá nguy hiểm để bao giờ lưu trữ các literal dữ liệu mật khẩu ở mọi nơi. Điều này làm cho việc khôi phục không thể, nhưng khi ai đó quên hoặc mất mật khẩu, bạn có thể chạy qua một số kiểm tra và tạo mật khẩu mới.

+0

@Quinton: Đó là khá nhiều những gì tôi làm. Với các thư viện mã hóa .net nó sẽ băm mật khẩu và sau đó tôi chuyển nó vào DB và lưu trữ dưới dạng nhị phân. Tôi chỉ có thể so sánh mật khẩu bằng cách băm đầu vào của người dùng và so sánh nó với những gì được lưu trữ. – TheTXI

+0

Có vẻ như bạn đang đi đúng hướng rồi. –

+1

Tôi khuyên bạn nên jbcrypt nếu bạn đang làm việc với java. Cực kỳ đơn giản để sử dụng –

15

Tôi làm điều tương tự như bạn đã mô tả, ngoại trừ nó được lưu trữ dưới dạng Chuỗi. I Base64 mã hóa giá trị nhị phân được mã hóa. Số lượng không gian để phân bổ phụ thuộc vào thuật toán mã hóa/độ mạnh mã hóa.

Tôi nghĩ bạn đang làm đúng (với điều kiện bạn sử dụng Salt).

+2

+1 để giải quyết câu hỏi thực sự tại đây. – erickson

46

Phương thức ưu tiên: không bao giờ lưu trữ mật khẩu trong DB của bạn. Chỉ có băm của chúng. Thêm muối để nếm.

+5

mod up, đã phải làm điều đó, chỉ cho các trò đùa muối;) – Jakub

+0

tôi cười toe toét vào nó là tốt. –

8

Vì kết quả của hàm băm là một chuỗi byte trong phạm vi từ 0 đến 255 (hoặc -128 đến 127, tùy thuộc vào ký hiệu của loại dữ liệu 8 bit), lưu trữ nó dưới dạng trường nhị phân thô làm cho ý nghĩa nhất, vì nó là đại diện nhỏ gọn nhất và không yêu cầu thêm các bước mã hóa và giải mã.

Một số cơ sở dữ liệu hoặc trình điều khiển không có hỗ trợ tuyệt vời cho các loại dữ liệu nhị phân hoặc đôi khi các nhà phát triển không đủ quen thuộc để họ cảm thấy thoải mái. Trong trường hợp đó, sử dụng mã hóa nhị phân thành văn bản như Base-64 hoặc Base-85 và việc lưu trữ văn bản kết quả trong trường ký tự là chấp nhận được.

Kích thước của trường cần thiết được xác định bởi hàm băm mà bạn sử dụng. MD5 luôn luôn xuất ra 16 byte, SHA-1 luôn xuất ra 20 byte. Khi bạn chọn hàm băm, bạn thường bị kẹt với nó, vì thay đổi yêu cầu đặt lại tất cả mật khẩu hiện có. Vì vậy, sử dụng trường có kích thước biến không mua cho bạn bất kỳ thứ gì.


Về cách "tốt nhất" để thực hiện băm, tôi đã cố gắng để cung cấp nhiều câu trả lời cho câu hỏi SO khác về chủ đề đó:

+0

Nếu bạn đọc câu hỏi của tôi một chút chặt chẽ hơn, bạn sẽ thấy tôi tập trung nhiều hơn cùng với lưu trữ thực tế trong điều khoản của datatype và không gian được phân bổ cho lĩnh vực này. – TheTXI

+0

Nhưng +1 để cung cấp thêm thông tin cho những người khác có thể đến sau. – TheTXI

+0

Bật. Có vẻ như tôi không phải là người duy nhất bỏ lỡ điều đó;) – erickson

8
  1. cửa hàng băm của muối mật khẩu, chẳng hạn như bcrypt (nounce + pwd). Bạn có thể thích bcrypt hơn SHA1 hoặc MD5 bởi vì nó có thể được điều chỉnh để được CPU-chuyên sâu, do đó làm cho một cuộc tấn công bạo lực cách lâu hơn.
  2. thêm hình ảnh xác thực vào biểu mẫu đăng nhập sau một vài lỗi đăng nhập (để tránh các cuộc tấn công bạo lực)
  3. nếu ứng dụng của bạn có liên kết "quên mật khẩu", đảm bảo không gửi mật khẩu mới qua email, nhưng thay vào đó nó sẽ gửi một liên kết đến một trang (bảo mật) cho phép người dùng xác định một mật khẩu mới (có thể chỉ sau khi xác nhận một số thông tin cá nhân, chẳng hạn như ngày sinh của người dùng, ví dụ). Ngoài ra, nếu ứng dụng của bạn cho phép người dùng xác định mật khẩu mới, hãy đảm bảo bạn yêu cầu người dùng xác nhận mật khẩu hiện tại.
  4. và rõ ràng, đảm bảo hình thức đăng nhập (thường là với HTTPS) và các máy chủ tự

Với các biện pháp này, mật khẩu của người dùng của bạn sẽ được bảo vệ khá tốt đối với:

  1. => ẩn tấn công từ điển
  2. => tấn công từ điển trực tiếp
  3. => tấn công từ chối dịch vụ
  4. => tất cả các loại tấn công!
+0

Tất cả các biện pháp này có thể được thực hiện nhanh chóng và đóng gói khá một cú đấm cho nỗ lực tối thiểu! +1 =) –

+0

Các cuộc tấn công DOS có liên quan đến bảo mật mật khẩu không? – Arj

+1

@ a12jun: nếu bạn có liên kết "quên mật khẩu của tôi" trên trang web của mình bằng thông tin đăng nhập "đăng nhập" đơn giản và nút "vui lòng tạo mật khẩu mới và gửi mật khẩu cho tôi qua email", thì bất kỳ ai biết thông tin đăng nhập của bạn có thể buộc bạn phải thay đổi mật khẩu của mình. Nếu anh ta tự động hóa việc này để chạy 10 giây một lần, thì anh ta có thể từ chối bạn truy cập vào tài khoản của bạn. Nếu anh ta điều này chống lại hàng ngàn người dùng, anh ta có thể nhận được rất nhiều người trong số họ không thích dịch vụ của bạn. Hướng dẫn # 3 có thể bảo vệ bạn chống lại điều này, đó là những gì tôi có nghĩa là (nó không phải là rất rõ ràng, tôi phải thừa nhận). Bảo mật = Bảo ​​mật, Tính toàn vẹn, *** Tính khả dụng ***. – MiniQuark

4

Băm đơn giản của mật khẩu hoặc thậm chí là (muối + mật khẩu) thường không đầy đủ.

xem:

http://www.matasano.com/log/958/enough-with-the-rainbow-tables-what-you-need-to-know-about-secure-password-schemes/

http://gom-jabbar.org/articles/2008/12/03/why-you-should-use-bcrypt-to-store-your-passwords

Cả hai giới thiệu các thuật toán bcrypt. Việc triển khai miễn phí có thể được tìm thấy trực tuyến cho hầu hết các ngôn ngữ phổ biến.

+0

Các liên kết tuyệt vời vượt ra ngoài những lo ngại về bảo mật bề ngoài. Đối với các thuật toán chậm cố ý, điều quan trọng là phải có các hash được tính toán ở phía máy khách để không làm quá tải máy chủ (có thể đã khá bận) chưa? – cheduardo

+0

Không thực sự. Mục tiêu chỉ đơn giản là làm cho nó "hơi" chậm hơn. Chỉ để cung cấp cho bạn một ý tưởng. Tôi có thể SHA1 băm khoảng 200K mật khẩu mỗi giây trên hệ thống lõi tứ. Tôi nghi ngờ bất cứ ai cần phải xử lý 200K đăng nhập đồng thời bao giờ thứ hai .... Vì vậy, bạn sử dụng một chức năng như PBKDF2 hoặc bcrypt để làm chậm nó xuống để nói chỉ 100 băm mỗi giây (tăng thời gian brute lực lượng của một yếu tố 200). –

2

Nếu bạn đang làm việc với ASP.Net, bạn có thể sử dụng API thành viên được tích hợp sẵn.

Nó hỗ trợ nhiều loại tùy chọn lưu trữ, inlcuding; băm một chiều, mã hóa hai chiều, md5 + muối. http://www.asp.net/learn/security để biết thêm thông tin.

Nếu bạn không cần bất cứ điều gì quá ưa thích, điều này là rất tốt cho các trang web.

Nếu bạn không sử dụng ASP.Net đây là một liên kết tốt để một vài bài viết từ 4guys và CodeProject

http://aspnet.4guysfromrolla.com/articles/081705-1.aspx http://aspnet.4guysfromrolla.com/articles/103002-1.aspx http://www.codeproject.com/KB/security/SimpleEncryption.aspx

4

tôi sử dụng băm sha của tên người dùng, một guid trong cấu hình web và mật khẩu, được lưu trữ dưới dạng varchar (40). Nếu họ muốn bạo lực/từ điển họ sẽ cần phải hack máy chủ web cho các guid là tốt. Tên người dùng phá vỡ việc tạo một bảng cầu vồng trên toàn bộ cơ sở dữ liệu nếu họ tìm thấy mật khẩu. Nếu người dùng muốn thay đổi tên người dùng của họ, tôi chỉ cần đặt lại mật khẩu cùng một lúc.

System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(
    username.ToLower().Trim(), 
    ConfigurationManager.AppSettings("salt"), 
    password 
); 
+0

tôi đã từng sử dụng tên người dùng là muối được thêm vào. Nhưng sau đó chúng tôi không thể đổi tên người dùng. Chúng tôi chuyển sang sử dụng muối với id, guid, sid, hoặc khóa thay thế khác của người dùng. –

+0

tru, gọi tốt. bằng cách này bạn không cần phải đặt lại mật khẩu khi bạn đổi tên một người dùng – Shawn

3

Bạn có thể sử dụng nhiều băm trong cơ sở dữ liệu của mình, chỉ cần thêm một chút nỗ lực. Nó cũng có giá trị nó mặc dù nếu bạn nghĩ rằng có cơ hội remotest bạn sẽ cần phải hỗ trợ định dạng bổ sung trong tương lai.Tôi thường sẽ sử dụng các mục mật khẩu như

{hashId} $ {muối} $ {băm mật khẩu}

nơi "hashId" chỉ là một số số tôi sử dụng trong nội bộ để nhận ra rằng, ví dụ như, tôi đang sử dụng SHA1 với một mẫu băm cụ thể; "muối" là muối ngẫu nhiên được mã hóa base64; và "băm mật khẩu" là băm mã hóa base64. Nếu bạn cần di chuyển băm, bạn có thể chặn mọi người bằng định dạng mật khẩu cũ và làm cho họ thay đổi mật khẩu của họ vào lần đăng nhập tiếp theo.

Vì những người khác đã đề cập bạn muốn cẩn thận với băm của mình đó là không thực sự an toàn, ví dụ, H (muối, mật khẩu) là yếu hơn H (mật khẩu, muối), nhưng đồng thời bạn muốn cân bằng nỗ lực đưa vào điều này với giá trị của nội dung trang web. Tôi thường sử dụng H (H (mật khẩu, muối), mật khẩu).

Cuối cùng, chi phí sử dụng mật khẩu được mã hóa base64 là khiêm tốn khi so sánh với lợi ích của việc có thể sử dụng các công cụ khác nhau mong đợi dữ liệu văn bản. Vâng, họ nên linh hoạt hơn, nhưng bạn đã sẵn sàng để nói với sếp của bạn rằng anh ta không thể sử dụng công cụ của bên thứ ba yêu thích của bạn bởi vì bạn muốn lưu một vài byte cho mỗi bản ghi? :-)

Đã chỉnh sửa để thêm một nhận xét khác: nếu tôi đề xuất cố ý sử dụng thuật toán đã đốt cháy ngay cả 1/10 giây băm mỗi mật khẩu, tôi sẽ may mắn khi được cười ra khỏi văn phòng của sếp. (Không may mắn như vậy? Anh ấy sẽ viết một cái gì đó xuống để thảo luận tại đánh giá hàng năm tiếp theo của tôi.) Đốt thời gian đó không phải là một vấn đề khi bạn có hàng tá, hoặc thậm chí hàng trăm người dùng. Nếu bạn đang đẩy 100 nghìn người dùng, bạn thường sẽ có nhiều người đăng nhập cùng một lúc. Bạn cần thứ gì đó nhanh và mạnh, không chậm và mạnh. "Nhưng những gì về thông tin thẻ tín dụng?" là không trung thực nhất kể từ khi thông tin thẻ tín dụng được lưu trữ không nên ở bất cứ đâu gần cơ sở dữ liệu thông thường của bạn và sẽ được mã hóa bởi ứng dụng, chứ không phải người dùng cá nhân.

+0

Không có thứ gì như nhanh và mạnh khi nói đến băm. Lấy làm tiếc.Nếu nó là nhanh chóng cho bạn nó là nhanh chóng cho một kẻ tấn công bạo lực. Sử dụng một hàm dẫn xuất quan trọng là một phương thức hợp lệ để tăng cường mật khẩu. –

2

Vì câu hỏi của bạn là về phương pháp lưu trữ &, tôi sẽ giải quyết vấn đề đó.

Loại lưu trữ có thể là biểu diễn nhị phân hoặc văn bản (base64 là phổ biến nhất). Nhị phân nhỏ hơn nhưng tôi thấy làm việc với văn bản dễ dàng hơn. Nếu bạn đang làm cho mỗi người dùng salting (muối khác nhau cho mỗi mật khẩu) sau đó nó dễ dàng hơn để lưu trữ muối + băm như là một chuỗi kết hợp duy nhất.

Kích thước phụ thuộc vào thuật toán băm. Đầu ra của MD5 luôn là 16 byte, SHA1 luôn là 20 byte. SHA-256 & SHA-512 là 32 & 64 byte tương ứng. Nếu bạn đang sử dụng mã hóa văn bản, bạn sẽ cần lưu trữ nhiều hơn một chút tùy thuộc vào phương pháp mã hóa. Tôi có xu hướng sử dụng Base64 vì lưu trữ tương đối rẻ. Base64 sẽ đòi hỏi khoảng 33% trường lớn hơn.

Nếu bạn có mỗi người dùng salting bạn sẽ cần không gian cho băm cũng. Đặt nó tất cả cùng nhau 64bit muối + SHA1 băm (160 bit) base64 mã hóa mất 40 ký tự vì vậy tôi lưu trữ nó như char (40).

Cuối cùng, nếu bạn muốn làm điều đó đúng, bạn không nên sử dụng một hàm băm đơn lẻ mà là một hàm dẫn xuất quan trọng như RBKDF2. Băm SHA1 và MD5 cực kỳ nhanh. Ngay cả một ứng dụng đơn luồng có thể băm khoảng 30K đến 50K mật khẩu mỗi giây với mật khẩu lên đến 200K mỗi giây trên máy lõi tứ. GPU có thể băm 100x đến 1000x như nhiều mật khẩu mỗi giây.Với tốc độ như thế lực tấn công bạo lực đó trở thành một phương pháp xâm nhập có thể chấp nhận được. RBKDF2 cho phép bạn chỉ định số lần lặp lại để tinh chỉnh cách băm của bạn "chậm". Điểm không phải là để đưa hệ thống đến đầu gối của nó mà là chọn một số lần lặp để bạn giới hạn trên mức thông lượng băm (nói 500 băm mỗi giây). Một phương pháp chứng minh trong tương lai sẽ bao gồm số lần lặp lại trong trường mật khẩu (lặp + muối + băm). Điều này sẽ cho phép tăng lặp lại trong tương lai để bắt kịp với các bộ vi xử lý mạnh mẽ hơn.Để sử dụng linh hoạt hơn, hãy sử dụng varchar để cho phép các băm có thể lớn hơn/thay thế trong tương lai.

Việc thực hiện Net là RFC2892DeriveBytes http://msdn.microsoft.com/en-us/library/system.security.cryptography.rfc2898derivebytes.aspx

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