it-swarm-vi.com

Mật khẩu băm: thêm muối + hạt tiêu hay muối là đủ?

Xin lưu ý: Tôi biết rằng phương pháp thích hợp để băm lưu trữ mật khẩu an toàn là mã hóa hoặc bcrypt. Câu hỏi này không phải để thực hiện trong phần mềm thực tế, nó là sự hiểu biết của riêng tôi.

Liên quan


Nền
[.__.] Theo như tôi biết, phương pháp được đề xuất/phê duyệt để lưu trữ trình xác minh mật khẩu là lưu trữ:

$verifier = $salt + hash( $salt + $password )

Ở đâu:

  • hash() là thuật toán băm mật mã
  • $salt Là giá trị entropy ngẫu nhiên, phân bố đều, cao
  • $password Là mật khẩu được nhập bởi người dùng

Một số người khuyên nên thêm một khóa bí mật vào hỗn hợp (đôi khi được gọi là pepper ). Trong đó hạt tiêu là một bí mật, entropy cao, hằng số hệ thống cụ thể.

Lý do có vẻ là ngay cả khi kẻ tấn công nắm giữ các trình xác minh mật khẩu, vẫn có khả năng người đó không biết giá trị của hạt tiêu. Vì vậy, gắn kết một cuộc tấn công thành công trở nên khó khăn hơn.

Vì vậy, câu hỏi của tôi là:
[.___.] Việc thêm một giá trị hạt tiêu ngoài muối khi băm mật khẩu có làm tăng tính bảo mật tổng thể không?

Hoặc là sự tăng cường nhận thức bảo mật dựa trên các giả định sai?

Cập nhật nhanh
[.__.] Tôi biết mục đích của $salt (Tôi đã viết khá câu trả lời dài trên StackOverflow về nó) khóa $pepper Bổ sung là không cải thiện những gì muối làm.
[.___.] Câu hỏi là, $pepper Có thêm bất kỳ bảo mật nào không khác so với những gì muối làm?

234
Jacco

Trong một số trường hợp, ớt có thể hữu ích.

Ví dụ điển hình, giả sử bạn đang xây dựng một ứng dụng web. Nó bao gồm mã webapp (chạy trong một số khung webapp, ASP.NET MVC, Kim tự tháp trên Python, không quan trọng) và Cơ sở dữ liệu SQL để lưu trữ. Webapp và SQL DB chạy trên các máy chủ vật lý khác nhau.

Cuộc tấn công phổ biến nhất đối với cơ sở dữ liệu là Cuộc tấn công SQL tiêm thành công. Kiểu tấn công này không nhất thiết phải có quyền truy cập vào mã webapp của bạn, vì ứng dụng web chạy trên một máy chủ và ID người dùng khác.

Bạn cần lưu trữ mật khẩu an toàn trong cơ sở dữ liệu và đưa ra một cái gì đó dưới dạng:

$hashed_password = hash( $salt . $password )

trong đó $salt được lưu trữ trong văn bản gốc trong cơ sở dữ liệu, cùng với đại diện $hashed_password được chọn ngẫu nhiên cho mỗi mật khẩu mới hoặc đã thay đổi.

khía cạnh quan trọng nhất của mọi lược đồ băm mật khẩu hash là một chậm Hàm băm bảo mật bằng mật mã, xem https://security.stackexchange.com/a/31846/10727 để biết thêm kiến ​​thức cơ bản.

Khi đó, câu hỏi đặt ra là cho rằng hầu như không có nỗ lực nào để thêm giá trị không đổi vào mã ứng dụng và mã ứng dụng thường sẽ Không bị xâm phạm trong SQL Attack Attack, sau đây có tốt hơn về cơ bản không?

$hashed_password = hash( $pepper . $salt . $password )

trong đó $salt được lưu trữ trong bản rõ trong cơ sở dữ liệu và $pepper là một hằng số được lưu trữ trong bản rõ trong mã ứng dụng (hoặc cấu hình nếu mã được sử dụng trên nhiều máy chủ hoặc nguồn là công khai).

Việc thêm $pepper Thật dễ dàng - bạn chỉ cần tạo một hằng số trong mã của mình, nhập một giá trị ngẫu nhiên lớn được bảo mật bằng mật mã (ví dụ: 32byte từ/dev/urandom hex hoặc base64 được mã hóa) vào đó và sử dụng hằng số trong chức năng băm mật khẩu. Nếu bạn có người dùng hiện tại, bạn cần một chiến lược di chuyển, ví dụ: thử lại mật khẩu trong lần đăng nhập tiếp theo và lưu trữ số phiên bản của chiến lược băm mật khẩu cùng với hàm băm.

Câu trả lời:

Sử dụng $pepper sẽ thêm vào độ mạnh của hàm băm mật khẩu if thỏa hiệp của cơ sở dữ liệu không ngụ ý thỏa hiệp của ứng dụng. Không có kiến ​​thức về hạt tiêu, mật khẩu vẫn hoàn toàn an toàn. Do muối mật khẩu cụ thể, bạn thậm chí không thể tìm ra liệu hai mật khẩu trong cơ sở dữ liệu có giống nhau hay không.

Lý do là vì hash($pepper . $salt . $password) xây dựng hiệu quả một hàm ngẫu nhiên giả với $pepper Làm khóa và $salt.$password Làm đầu vào (cho sane hash các ứng cử viên như PBKDF2 với SHA * , bcrypt hoặc tiền điện tử). Hai trong số các đảm bảo của hàm ngẫu nhiên giả là bạn không thể suy ra đầu vào từ đầu ra dưới một khóa bí mật và không phải đầu ra từ đầu vào mà không có kiến ​​thức về khóa. Điều này nghe có vẻ giống như thuộc tính một chiều của hàm băm, nhưng sự khác biệt nằm ở chỗ với các giá trị entropy thấp như mật khẩu, bạn có thể liệt kê hiệu quả tất cả các giá trị có thể và tính toán các hình ảnh theo hàm băm công khai và do đó tìm giá trị hình ảnh phù hợp với hình ảnh trước. Với hàm ngẫu nhiên giả, bạn không thể làm như vậy nếu không có khóa (tức là không có tiêu) vì bạn thậm chí không thể tính hình ảnh của một giá trị mà không có khóa.

Vai trò quan trọng của $salt Trong cài đặt này sẽ xuất hiện nếu bạn có quyền truy cập vào cơ sở dữ liệu trong một thời gian dài và bạn vẫn có thể làm việc bình thường với ứng dụng từ bên ngoài. Nếu không có $salt, Bạn có thể đặt mật khẩu của tài khoản bạn kiểm soát thành giá trị đã biết $passwordKnown Và so sánh hàm băm với mật khẩu của mật khẩu không xác định $passwordSecret. Vì hash($pepper . $passwordKnown)==hash($pepper . $passwordSecret) if và only if $passwordKnown==$passwordSecret Bạn có thể so sánh mật khẩu không xác định với bất kỳ giá trị được chọn nào (vì tính kỹ thuật tôi giả sử khả năng chống va chạm của hàm băm). Nhưng với muối, bạn nhận được hash($pepper . $salt1 . $passwordKnown)==hash($pepper . $salt2 . $passwordSecret) khi và chỉ khi $salt1 . $passwordKnown == $salt2 . $passwordSecret Và như $salt1$salt2 Lần lượt được chọn ngẫu nhiên cho $passwordKnown$passwordSecret Các muối sẽ không bao giờ giống nhau (giả sử các giá trị ngẫu nhiên đủ lớn như 256bit) và do đó bạn không còn có thể so sánh mật khẩu với nhau.

195
Jesper M

(Lưu ý: sử dụng muối chỉ là một nửa công việc; bạn cũng cần làm cho hàm băm chậm - để việc tấn công một mật khẩu entropy thấp duy nhất vẫn còn khó khăn. 10000 bản muối và mật khẩu.)

Cái "tiêu" của bạn làm là nó biến hàm băm thành MAC . Tạo một MAC tốt, an toàn từ hàm băm là không dễ, vì vậy bạn nên sử dụng tốt hơn HMAC thay vì xây dựng tự chế (cách đặt lý thuyết đó là hàm băm chống va chạm không nhất thiết không thể phân biệt được với một Oracle ngẫu nhiên).

Với MAC, bạn có thể đạt được một số bảo mật theo nghĩa sau: có thể, cơ sở dữ liệu truy cập đọc bởi kẻ tấn công có thể không còn là vấn đề thực sự. Khóa MAC ("hạt tiêu") có thể tập trung nhu cầu bảo mật. Tuy nhiên, điều này phụ thuộc vào MAC cũng là chức năng một chiều, đây là một tài sản mà bạn sẽ nhận được từ nhiều công trình MAC (bao gồm cả HMAC) nhưng không thực sự được bảo đảm về mặt mật mã học (có sự tinh tế).

"Hạt tiêu" ngụ ý rằng bạn có một chìa khóa để quản lý, bao gồm lưu trữ an toàn theo cách chống lại việc khởi động lại. Một khóa nhỏ và vừa với RAM, nhưng, do yêu cầu lưu trữ, không rõ liệu nó có thực sự cải thiện bảo mật hay không. Kẻ tấn công có thể đọc toàn bộ cơ sở dữ liệu thường cũng có thể đọc toàn bộ đĩa cứng, bao gồm mọi tệp "được bảo vệ". Kích thước nhỏ của khóa có thể cho phép một số thiết lập nâng cao, ví dụ: khóa được lưu trữ trên thẻ thông minh được sử dụng khi khởi động nhưng không được kết nối sau đó. Tóm lại, việc tiêu có đáng để nỗ lực triệt để hay không phụ thuộc vào bối cảnh - trên cơ sở chung, tôi sẽ đề nghị chống lại nó, để tránh sự phức tạp thêm vào.

90
Thomas Pornin

Tôi muốn chỉ ra những gì một hạt tiêu thực sự có thể làm.

Khi nào một hạt tiêu giúp?

Như những người khác đã chỉ ra, thêm hạt tiêu chỉ là một lợi thế, miễn là kẻ tấn công có quyền truy cập vào các giá trị băm trong cơ sở dữ liệu, nhưng không có quyền kiểm soát máy chủ, và do đó không biết hạt tiê. Đây là điển hình cho SQL-tiêm, có lẽ là một trong những cuộc tấn công thường được sử dụng, bởi vì nó rất dễ thực hiện.

Hạt tiêu cải thiện điều gì?

$hashValue = bcrypt('12345', $cost, $salt);

Mật khẩu này bạn có thể dễ dàng nhận được bằng một cuộc tấn công từ điển, ngay cả khi bạn sử dụng đúng chức năng dẫn xuất khóa chậm. Đặt mật khẩu được sử dụng nhiều nhất vào từ điển và vũ phu với mật khẩu yếu này. Rất có khả năng chúng tôi tìm thấy mật khẩu trong (quá) nhiều trường hợp.

$hashValue = bcrypt('12345anm8e3M-83*2cQ1mlZaU', $cost, $salt);

Với hạt tiêu, mật khẩu yếu phát triển theo chiều dài, giờ đây nó chứa các ký tự đặc biệt và quan trọng hơn, bạn sẽ tìm thấy nó trong không có từ điển. Vì vậy, miễn là hạt tiêu giữ bí mật, nó sẽ ngăn chặn các cuộc tấn công từ điển, trong trường hợp này nó có thể bảo vệ mật khẩu yếu.

Biên tập:

Có một cách tốt hơn để thêm khóa phía máy chủ, hơn là sử dụng nó làm tiêu. Với một hạt tiêu, kẻ tấn công phải giành được các đặc quyền bổ sung trên máy chủ để lấy chìa khóa. Lợi thế tương tự chúng ta có được bằng cách tính toán hàm băm trước và sau đó mã hóa hàm băm bằng khóa bên máy chủ (mã hóa hai chiều). Điều này cho chúng ta tùy chọn để trao đổi khóa bất cứ khi nào cần thiết.

$hash = bcrypt($passwort, $salt);
$encryptedHash = encrypt($hash, $serverSideKey);
26
martinstoeckli

Bài viết về phát minh muối và lặp, cho mật khẩu Unix ( Mật khẩu bảo mật: Lịch sử trường hợp, Morris & Thompson, 1978 ), cũng mô tả tương đương với hạt tiêu:

Tám ký tự đầu tiên của mật khẩu người dùng được sử dụng làm khóa cho DES; sau đó thuật toán được sử dụng để mã hóa một hằng số. Mặc dù hằng số này bằng không tại thời điểm này, nó có thể dễ dàng truy cập và có thể được thực hiện phụ thuộc vào cài đặt.

Tôi chưa nghe nói về nó được sử dụng mặc dù. Có ai khác không?

9
nealmcb

Chỉ cần một BTW, Hướng dẫn về ý tưởng kỹ thuật số (Bản nháp) mới của NIST cũng khuyên bạn nên sử dụng Pepper:

https://pages.nist.gov/800-63-3/sp800-63b.html#sec5

5.1.1.2 Trình xác minh bí mật ghi nhớ:

... Hàm băm có khóa (ví dụ: HMAC [Trin198-1]), với khóa được lưu riêng biệt với các trình xác thực băm (ví dụ: trong mô-đun bảo mật phần cứng) NÊN sử dụng để chống lại các cuộc tấn công từ điển đối với các trình xác thực băm được lưu trữ.

7
eckes

Hãy xem xét kịch bản này:

Tôi sắp đột nhập vào một trang web X bằng cách sử dụng SQL SQL để lấy danh sách người dùng, với mật khẩu băm và muối. Giả sử trang web X cũng đang sử dụng hạt tiêu toàn cầu.

Tất cả những gì tôi phải làm là đăng ký người dùng tại trang web X với tên người dùng và mật khẩu mà tôi biết trước khi tiêm SQL. Sau đó tôi sẽ biết, đối với một bản ghi cụ thể trong cơ sở dữ liệu, hàm băm mật khẩu, mật khẩu văn bản đơn giản, muối (được lưu trữ dưới dạng văn bản thuần túy) và nó sẽ là tầm thường đối với tôi để phá vỡ hồ tiêu toàn cầu trên cơ sở một bản ghi này .

Vì vậy, thực sự, một hạt tiêu sẽ là một cách làm chậm kẻ tấn công trong một khoảng thời gian không đáng kể. Họ sẽ không phải ép buộc mật khẩu + muối + hạt tiêu, như dự định, chỉ có hạt tiêu.

Trên đây là một hình thức tấn công bằng văn bản đã chọn. Miễn là kẻ tấn công biết thuật toán (hash ()), đầu ra ($ hashed_password) và tất cả trừ một trong những đầu vào ("hằng" $ salt & $ password và "biến" $ pepper), chúng có thể "giải quyết cho x "Giống như một phương trình đại số tuyến tính (h = s + p + x == hsp = x), nhưng tất nhiên là bằng sức mạnh vũ phu. Làm cho tiêu dài hơn 56 byte (448 bit), giới hạn của bcrypt, làm tăng chi phí thời gian và tốt như bcrypt nhưng vẫn có thể không tốt như tiền điện tử. Vì vậy, miễn là hạt tiêu đủ dài, đó là một sự cải tiến.

4
Alex R

Không quen thuộc lắm về cách một máy chủ có thể ẩn hằng số tiêu toàn cầu, nhưng tôi nghĩ rằng sớm muộn một hacker đã xâm nhập máy chủ sẽ tìm ra cách nắm bắt giá trị của hạt tiêu. Để làm cho giá trị hồ tiêu hoàn toàn an toàn sẽ cần phần cứng đặc biệt. Một cách để làm điều này là sử dụng một bo mạch đồ họa được cài đặt trong máy chủ. FPGA sẽ chứa mã được sử dụng để thực hiện hàm băm bao gồm giá trị tiêu và tất cả các phép tính băm xảy ra bên trong FPGA. Với FPGA, lập trình có thể là một chức năng một chiều. Hạt tiêu có thể được lập trình trong nhưng không có hướng dẫn nào có thể được gửi để đọc lại. Hạt tiêu sẽ được lưu trữ trên một mảnh giấy được khóa trong két sắt. Nếu tiêu có hơn 128 bit được tạo ngẫu nhiên, sẽ không có cách xác định thực tế nào.
[.__.] Không chắc điều này sẽ thực tế đến mức nào vì nó sẽ làm tăng chi phí phần cứng máy chủ.

1
Brian Sparks