2009-08-02 50 views
222

Tôi đã luôn sử dụng chuỗi muối thích hợp cho mỗi lần nhập khi mật khẩu băm để lưu trữ cơ sở dữ liệu. Đối với nhu cầu của tôi, việc lưu trữ muối trong DB bên cạnh mật khẩu băm luôn hoạt động tốt.Bạn lưu chuỗi muối ở đâu?

Tuy nhiên, một số người khuyên rằng muối được lưu trữ riêng biệt với cơ sở dữ liệu. Lập luận của họ là nếu cơ sở dữ liệu bị xâm nhập, kẻ tấn công vẫn có thể xây dựng một bảng cầu vồng lấy một chuỗi muối cụ thể để giải mã một tài khoản tại một thời điểm. Nếu tài khoản này có đặc quyền quản trị viên, thì có thể anh ấy thậm chí không cần phải bẻ khóa bất kỳ người nào khác.

Từ quan điểm bảo mật, có đáng để lưu trữ muối ở một nơi khác không? Hãy xem xét một ứng dụng web với mã máy chủ và DB trên cùng một máy. Nếu các muối được lưu trữ trong một tập tin phẳng trên máy đó, rất có thể là nếu cơ sở dữ liệu bị xâm nhập, các tập tin muối sẽ được, quá.

Có giải pháp được đề xuất nào cho điều này không?

+7

Nếu có nơi bạn có thể lưu trữ muối mà kẻ tấn công không thể nhận được, thì bạn cũng nên lưu trữ mật khẩu ở đó. Nhưng tại sao không sử dụng một loại muối khác nhau cho mỗi mật khẩu? – jrockway

+6

Anh ấy đang sử dụng một loại muối khác nhau cho mỗi mật khẩu, jrockway. – Amber

+9

Muối của bạn lớn đến mức nào? Các muối của bạn phải đủ lớn (32 bit?) Mà thực tế không có khả năng là một chiếc bàn cầu vồng đã được precomputed cho nó. –

Trả lời

232

Điểm của các bảng cầu vồng là chúng được tạo ra trước và phân tán để tiết kiệm thời gian tính toán cho người khác - chỉ mất khoảng thời gian dài để tạo ra các bảng cầu vồng khi nó chỉ cần crack mật khẩu + muối kết hợp trực tiếp (kể từ khi có hiệu quả những gì đang được thực hiện khi tạo ra các bảng cầu vồng là trước khi chạy các tính toán cho brute-buộc băm), do đó lập luận rằng bằng cách biết muối ai đó có thể "tạo ra một bảng cầu vồng" là giả mạo.

Không có điểm thực trong việc lưu trữ muối trong một tệp riêng biệt miễn là chúng trên cơ sở mỗi người dùng - điểm của muối đơn giản là làm cho nó sao cho một bảng cầu vồng không thể phá vỡ mọi mật khẩu DB.

+15

Đồng ý. Mô hình mối đe dọa bạn đang bảo vệ chống lại bằng cách lưu trữ muối riêng biệt là một người dùng bằng cách nào đó có thể truy cập vào muối trong DB thông qua các phương tiện bất chính, nhưng không phải là băm (trong DB). Và rằng người đó sẽ bắt đầu tính toán một bảng cầu vồng trước, giả sử anh ta sẽ có thể tìm thấy băm sau này. Không phải không thể, nhưng cũng không có giá trị nỗ lực kỹ thuật để bảo vệ aginst con đường tấn công duy nhất này. –

+0

Bài viết hay, tôi đã tự hỏi điều tương tự. Tôi chưa bao giờ nghĩ về một muối cho mỗi người dùng, tôi đã nghĩ rằng một muối đơn sẽ có hiệu quả đối với tất cả người dùng. Điều gì về một muối được lưu trữ như một tập tin XML được tải bởi máy chủ ứng dụng? hoặc có thể bằng cách nào đó mã hóa thành một servlet? – Jigzat

+8

@Jigzat - Salting là vô nghĩa nếu bạn không có muối riêng cho mỗi người dùng. Điểm mấu chốt là phá vỡ các băm một nhiệm vụ riêng biệt cho mỗi mật khẩu người dùng; nếu muối là như nhau cho tất cả trong số họ thì đó không phải là trường hợp. – Amber

22

Thông thường, chúng được thêm vào băm và được lưu trữ trong cùng một trường.

Không cần lưu trữ chúng riêng biệt - điểm là sử dụng một muối ngẫu nhiên cho mỗi mật khẩu sao cho không thể sử dụng một bảng cầu vồng duy nhất đối với toàn bộ bộ băm mật khẩu của bạn. Với các muối ngẫu nhiên, một kẻ tấn công phải brute-force mỗi băm riêng biệt (hoặc tính toán một bảng cầu vồng cho tất cả các muối có thể - bao la nhiều công việc hơn).

Nếu bạn có một vị trí lưu trữ an toàn hơn, sẽ có ý nghĩa khi chỉ lưu trữ các băm ở đó.

+3

Nhưng điều gì sẽ xảy ra nếu tất cả các mật khẩu băm bị rò rỉ bao gồm cả muối phù hợp? Không phải là không an toàn sao? – mghaoui

+8

@mghaoui Nhưng sau đó nếu bạn muốn biết "mật khẩu" bạn vẫn sẽ phải xây dựng một bảng cầu vồng cho mỗi và mọi muối, trừ khi một số muối là như nhau. – Franklin

32

Tôi sẽ cung cấp một chút khác biệt về điều này.

Tôi luôn lưu trữ muối được trộn lẫn với hàm băm được mã hóa bằng muối.

Ví dụ, tôi sẽ đặt nửa đầu của muối trước khi băm muối của mật khẩu, và nửa cuối của muối sau khi băm muối của mật khẩu. Ứng dụng này nhận thức được thiết kế này để có thể tìm nạp dữ liệu này và lấy hàm băm muối và mật khẩu muối.

lý do của tôi cho cách tiếp cận này:

Nếu dữ liệu mật khẩu/băm bị tổn thương và rơi vào tay của kẻ tấn công, kẻ tấn công sẽ không biết những gì muối là từ nhìn vào dữ liệu. Bằng cách này, kẻ tấn công không thể thực hiện tấn công brute-force để lấy mật khẩu khớp với băm, vì anh ta không biết băm để bắt đầu và không có cách nào để biết phần nào của dữ liệu là một phần của muối, hoặc các phần của hàm băm có mật khẩu muối (trừ khi anh ta biết logic xác thực của ứng dụng của bạn).

Nếu băm mật khẩu muối được lưu trữ dưới dạng, thì có thể thực hiện một cuộc tấn công brute-force để lấy mật khẩu khi muối và băm tạo ra cùng một dữ liệu như băm mật khẩu muối.

Tuy nhiên, ví dụ, ngay cả khi băm mật khẩu muối được lưu trữ dưới dạng, nhưng tiền được kích hoạt bằng một byte ngẫu nhiên duy nhất, miễn là kẻ tấn công không biết rằng byte đầu tiên này sẽ bị hủy. cũng làm tăng khó khăn của cuộc tấn công. Ứng dụng của bạn sẽ biết loại bỏ byte đầu tiên của dữ liệu khi được sử dụng để xác thực người dùng của bạn.

Kết luận này ..

1) Không bao giờ lưu trữ các dữ liệu mà ứng dụng xác thực của bạn sử dụng trong đó là hình thức chính xác.

2) Nếu có thể, hãy giữ bí mật logic xác thực của bạn để tăng cường bảo mật.

Go thêm một bước nữa ..

Nếu bạn không thể giữ bí mật xác thực logic của ứng dụng của bạn - rất nhiều người biết làm thế nào dữ liệu của bạn được lưu trữ trong cơ sở dữ liệu. Và giả sử bạn đã quyết định để lưu trữ băm mật khẩu muối trộn lẫn với muối, với một số muối prepending các băm mật khẩu muối, và phần còn lại của muối thêm nó.

Khi tạo muối ngẫu nhiên, bạn cũng có thể quyết định ngẫu nhiên tỷ lệ muối bạn sẽ lưu trữ trước/sau khi băm mật khẩu muối.

Ví dụ: bạn tạo một muối ngẫu nhiên là 512 byte. Bạn thêm muối vào mật khẩu của bạn, và lấy mã băm SHA-512 của mật khẩu muối của bạn. Bạn cũng tạo ra một số nguyên ngẫu nhiên 200. Sau đó bạn lưu trữ 200 byte đầu tiên của muối, tiếp theo là băm mật khẩu muối, tiếp theo là phần còn lại của muối.

Khi xác thực nhập mật khẩu của người dùng, ứng dụng của bạn sẽ vượt qua chuỗi và giả sử 1 byte đầu tiên của dữ liệu là 1 byte đầu tiên của muối, tiếp theo là hàm băm muối. Vé này sẽ không thành công. Ứng dụng sẽ tiếp tục bằng cách sử dụng 2 byte đầu tiên của dữ liệu là 2 byte đầu tiên của muối và lặp lại cho đến khi kết quả tích cực được tìm thấy sau khi sử dụng 200 byte đầu tiên làm 200 byte đầu tiên của muối. Nếu mật khẩu sai, ứng dụng sẽ tiếp tục thử tất cả các hoán vị cho đến khi không tìm thấy.

Các ưu điểm của phương pháp này:

Tăng an ninh - ngay cả nếu logic xác thực của bạn được biết đến, logic chính xác là chưa có thời gian biên dịch. Nó là thực tế không thể thực hiện một cuộc tấn công brute-force, ngay cả với kiến ​​thức về logic chính xác. Tăng độ dài của muối sẽ tăng cường an ninh hơn nữa.

Các nhược điểm của phương pháp này:

Kể từ logic chính xác được suy ra tại thời gian chạy, phương pháp này là rất CPU-chuyên sâu. Độ dài của muối càng dài thì phương pháp tiếp cận này càng nhiều CPU.

Xác thực mật khẩu không chính xác sẽ liên quan đến chi phí CPU cao nhất. Điều này có thể phản tác dụng với các yêu cầu hợp pháp, nhưng tăng cường an ninh chống lại kẻ tấn công.

Cách tiếp cận này có thể được thực hiện theo nhiều cách khác nhau và có thể được thực hiện an toàn hơn bằng cách sử dụng các muối có độ rộng biến đổi và/hoặc băm mật khẩu.

+5

Với cách tiếp cận của bạn, bạn chỉ cần thêm một bí mật vào quá trình băm của bạn (thuật toán áp dụng muối). Bí mật này bạn có thể thêm dễ dàng hơn nhiều với việc thêm ** ** pepper vào muối, tôi đã cố gắng chỉ ra điều này trong [hướng dẫn] của tôi (http://www.martinstoeckli.ch/hash/en/index.php) . Hàm băm hiện đại như BCrypt sẽ tự áp dụng muối, sử dụng muối ban đầu trong mỗi lần lặp, do đó bạn sẽ không thể kiểm soát điều này. – martinstoeckli

+0

@martinstoeckli Mặc dù bạn chính xác rằng BCrypt tự áp dụng muối, việc lưu trữ hàm băm + muối đó tùy thuộc vào bạn với tư cách là nhà phát triển. Vì vậy, bạn có thể dễ dàng thêm một tiêu vào muối + băm và tồn tại nó vào cơ sở dữ liệu. Sau đó, trong lần truy xuất tiếp theo, bạn đọc giá trị từ cơ sở dữ liệu, tách giá trị hạt tiêu và chuyển giá trị còn lại thành BCrypt. – PeterToTheThird

+1

@PeterToTheThird - Điều này sẽ phủ nhận lợi thế của hạt tiêu. Hạt tiêu thêm một bí mật phía máy chủ, và chỉ hoạt động miễn là nó giữ bí mật (đối diện với muối). Một cuộc tấn công điển hình là SQL-injection, khi ai đó có quyền truy cập vào cơ sở dữ liệu nhưng không phải mã, thì một hạt tiêu được lưu trữ trong cơ sở dữ liệu sẽ vô ích sau đó. Hầu hết các triển khai BCrypt sẽ tự động thêm muối vào giá trị băm kết quả, vì vậy giá trị này đã chứa muối, hệ số chi phí, thuật toán và hàm băm. Chuỗi này có thể được lưu trữ trong một trường có độ dài 60 ký tự. – martinstoeckli

3

Dựa trên phát triển ASP.NET MVC 4 Ứng dụng Web cuốn sách của William Penberthy:

  1. Tiếp cận được các muối được lưu trữ trong cơ sở dữ liệu riêng biệt đòi hỏi hacker hack hai cơ sở dữ liệu khác nhau để có được quyền truy cập vào các muối và mật khẩu muối. Lưu trữ chúng trong cùng bảng với mật khẩu, hoặc thậm chí một bảng khác của cùng một cơ sở dữ liệu, sẽ có nghĩa là khi tin tặc truy cập vào cơ sở dữ liệu, họ sẽ có quyền truy cập vào cả hai muối và băm mật khẩu. Bởi vì bảo mật bao gồm quá trình thực hiện hack vào hệ thống quá đắt hoặc tốn thời gian để đáng giá, tăng gấp đôi số tiền truy cập vào một hacker sẽ phải đạt được nên làm cho hệ thống an toàn hơn.
  2. Dễ sử dụng là lý do chính để giữ các muối trong cùng cơ sở dữ liệu với mật khẩu được băm . Bạn sẽ không phải đảm bảo rằng hai cơ sở dữ liệu luôn có sẵn cùng một lúc và luôn đồng bộ hóa. Lợi thế của việc có muối là tối thiểu nếu mỗi người dùng có một muối ngẫu nhiên bởi vì mặc dù nó có thể làm cho việc khám phá mật khẩu của một cá nhân dễ dàng hơn, số lượng lực cần thiết để bẻ khóa mật khẩu của hệ thống tổng thể là cao. Ở cấp độ thảo luận này, đó thực sự là kỳ vọng là: để bảo vệ mật khẩu. Nếu tin tặc đã mua bản sao của cơ sở dữ liệu, dữ liệu ứng dụng của bạn đã bị xâm phạm. Tại thời điểm này, vấn đề là giảm thiểu rủi ro của của người dùng vì tiềm năng của mật khẩu được chia sẻ.
  3. Yêu cầu duy trì hai cơ sở dữ liệu được liên kết riêng biệt là mở rộng. Cấp, nó thêm nhận thức về an ninh, nhưng lợi thế duy nhất mà nó mang lại là nó bảo vệ mật khẩu, một phần tử dữ liệu duy nhất. Nếu mọi trường trong cơ sở dữ liệu riêng lẻ được mã hóa và cùng một muối này được sử dụng cho điều đó, sẽ có ý nghĩa hơn khi lưu trữ nó tách biệt với dữ liệu vì bảo mật cơ bản của hệ thống của bạn được nâng cao.
Các vấn đề liên quan