2012-06-15 35 views
6

Khi xác thực người dùng vào trang web, việc tạo và so sánh băm được thực hiện trong cơ sở dữ liệu hoặc trang web là gì?Thực hành tốt nhất cho việc so sánh mật khẩu nên được thực hiện

Đối số của tôi là trang web phải chuyển mật khẩu do người dùng cung cấp (có thể được mã hóa bởi máy chủ web) vào cơ sở dữ liệu. Cơ sở dữ liệu sau đó mã hóa lại nó bằng muối và so sánh giá trị băm. Cơ sở dữ liệu đáp ứng với máy chủ web cho dù thông tin đăng nhập của người dùng có hợp lệ hay không. Bằng cách này, mức tối thiểu đã từng rời khỏi cơ sở dữ liệu, về cơ bản là có hoặc không, không có thông tin chứng chỉ được lưu trữ nào. Nhược điểm là, cơ sở dữ liệu phải làm nhiều việc hơn.

Đối số khác là công việc nên được thực hiện trong máy chủ web. Ở đây, máy chủ web sẽ tạo băm và yêu cầu băm được lưu trữ từ cơ sở dữ liệu và so sánh. Trong tình huống này, muối cần được chuyển từ cơ sở dữ liệu trở lại máy chủ web để tạo băm. nhưng, công việc được chia sẻ khi số lượng máy chủ web tăng lên.

Cá nhân tôi thấy phương pháp thứ hai là rủi ro bảo mật tiềm ẩn. Nếu máy chủ web bị xâm nhập, các muối và băm có thể được yêu cầu từ cơ sở dữ liệu và dễ bị bẻ khóa.

Thực tiễn tốt nhất để thực hiện thao tác trên là gì? Tôi có nhìn/bỏ sót gì không?

Cảm ơn

Trả lời

3

Vấn đề đầu tiên tôi nghi ngờ bạn sẽ gặp phải (và đó là vấn đề lớn) là cơ sở dữ liệu của bạn không có hàm băm mật khẩu. Chắc chắn, nó có thể có MD5() và SHA1() nhưng đây là các hàm băm mật mã. Nó có bcrypt() hoặc scrypt() hoặc PBKDF2()?

Sử dụng hàm băm mật mã thay vì hàm băm mật khẩu là điều có nghĩa là mật khẩu LinkedIn có thể bị bẻ khóa quá nhanh. Nếu bạn không sử dụng một trong các chức năng trên thì bạn sẽ bị tổn thương tương tự nếu băm của bạn bị rò rỉ.


Đi trên để trả lời câu hỏi của bạn giả định rằng cơ sở dữ liệu của bạn không hỗ trợ một thuật toán mật mã băm (sử dụng bcrypt đơn giản chỉ vì tôi phải chọn một).Hai lựa chọn thay thế là:

Băm trong cơ sở dữ liệu:

$db->query("SELECT COUNT(*) FROM users WHERE username = '?' AND password = BCRYPT(?, (SELECT salt FROM user WHERE username = '?'))", $username, $password, $username); 
if($row['count'] != 1) 
{ 
    // Not authenticated. Throw exception. 
} 

Trong trường hợp này, mật khẩu thô được gửi đến cơ sở dữ liệu và đơn giản có hoặc không có (1 hoặc 0) được trả về. Thông tin liên lạc cơ sở dữ liệu này có thể được mã hóa. Hàm băm và muối không bao giờ được giữ trong ứng dụng.

Băm trong ứng dụng:

$db->query("SELECT username, salt, password FROM users WHERE username = '?', $username); 
if(bcrypt($password, $row['salt']) != $row['password']) 
{ 
    // Not authenticated. Throw exception. 
} 

Trong trường hợp này, băm và muối được lấy ra từ cơ sở dữ liệu vào ứng dụng và băm của mật khẩu thô và so sánh được thực hiện ở đó. Giao tiếp với cơ sở dữ liệu vẫn có thể được mã hóa. Mật khẩu thô không bao giờ được giữ trong bộ nhớ cơ sở dữ liệu.

Để có hiệu quả, chúng ta có thể giả định rằng cả hai thuật toán băm được viết bằng C (hoặc một số ngôn ngữ được biên dịch) và có thể do hệ điều hành cung cấp để cùng một lúc. Tùy chọn băm ứng dụng nhận được nhiều dữ liệu hơn dây và tùy chọn băm cơ sở dữ liệu gửi nhiều hơn và có truy vấn phức tạp hơn (về cơ bản là hai truy vấn, một truy vấn để nhận được muối và một để thực hiện so sánh). Không thể sử dụng chỉ mục theo cách tôi đã viết truy vấn đó nhưng truy vấn có thể được viết lại. Vì kích thước của dữ liệu trong cả hai trường hợp có khả năng vẫn là một gói TCP, sự khác biệt về tốc độ sẽ không đáng kể. Tôi sẽ gọi đây là chiến thắng cho tùy chọn băm ứng dụng do truy vấn phụ.

Để hiển thị. Tôi sẽ xem xét các mật khẩu thô để được nhạy cảm hơn so với băm và muối với nhau. Vì vậy, hạn chế việc tiếp xúc với mật khẩu thô có vẻ như đặt cược an toàn hơn, khiến cho ứng dụng băm là cách thực hành tốt nhất.

+0

Tôi đoán tôi đã đơn giản hóa ví dụ nhưng bạn vẫn có thể nhúng phương thức mã hóa vào cơ sở dữ liệu, ví dụ như sử dụng các đối tượng clr trong máy chủ sql – Blootac

+0

@Blootac Điểm tốt. Tôi đã thêm một câu trả lời cho câu hỏi thực tế với giả định rằng cơ sở dữ liệu của bạn có một thuật toán băm thích hợp. – Ladadadada

+0

Cảm ơn bạn, mô tả tốt về ưu và nhược điểm. – Blootac

3

Bạn đang nhìn ra mục đích của một muối.

Muối được sử dụng để ngăn chặn cuộc tấn công từ điển vào mật khẩu băm. Nếu mật khẩu của bạn là "đậu phộng" và băm đến 12345, thì tôi có thể tạo trước danh sách các băm cho mỗi từ trong từ điển (bao gồm cả mật khẩu của bạn) và nhanh chóng tìm thấy mật khẩu của bạn bằng cách tra cứu bộ mật khẩu được tạo trước của tôi băm. Đây là những gì đã xảy ra với LinkedIn gần đây. Nếu mật khẩu được muối, tôi phải tạo trước một từ điển cho mỗi giá trị muối sau khi xâm phạm cơ sở dữ liệu, điều này sẽ cực kỳ tốn kém.

Hơn nữa, các muối được tạo ngẫu nhiên thích hợp ngăn chặn kẻ tấn công biết rằng bạn và tôi có cùng mật khẩu (không có muối, chúng tôi sẽ có cùng một băm).

Vấn đề của tôi là các muối không phải là một bí mật. Họ không phải là thông tin công khai, nhưng kẻ tấn công nhận được quyền truy cập vào các giá trị muối + băm không nhất thiết có nghĩa là mật khẩu đã bị xâm nhập.

0

Nguyên tắc chung về bảo mật máy tính là nếu bạn phải hỏi, bạn không nên tự mình làm điều đó. Nhưng nếu lo ngại của bạn là phơi bày chi tiết mật khẩu nếu máy chủ web bị xâm nhập, thì một cách tiếp cận là di chuyển xác thực vào hệ thống riêng của mình và không cho phép máy chủ web truy cập vào cơ sở dữ liệu mật khẩu.

+2

Tôi thấy quan điểm của bạn nhưng nếu không ai hỏi câu hỏi, không ai từng học và mọi người sẽ tiếp tục làm những việc sai. Đó là những người không hỏi những câu hỏi mà bạn nên quan tâm hơn. Cảm ơn bạn đã gợi ý. – Blootac

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