2010-08-24 55 views
9

Tôi đang thực hiện mô-đun cho phép người dùng đặt lại mật khẩu. Tôi nhận thấy hầu hết các trang web mà họ cung cấp liên kết xác nhận chứa chuỗi truy vấn có băm duy nhất.Tạo mã bí mật để đặt lại mật khẩu

Câu hỏi của tôi là: Làm cách nào để tạo băm duy nhất này mỗi khi cùng một yêu cầu người dùng quên mật khẩu? Tôi có nên lưu trữ băm này trong cơ sở dữ liệu và sử dụng nó để xác minh sau này không? Nó có an toàn không? Hoặc tôi có nên tạo một số thuật toán tạo mật khẩu một lần không? Tôi có thể tạo OTP bằng cách nào?

+6

Xin chào mọi người, xin trả lời. Im freaking bất ngờ bởi tốc độ phản ứng. WOW !! stackoverflow cộng đồng đá !! – nuttynibbles

Trả lời

26

Có, bạn nên

  1. Tạo một thẻ reset ngẫu nhiên. Xem ví dụ this answer.
  2. Lưu trữ trong cơ sở dữ liệu (có thể với thời gian hết hạn)
  3. Gửi e-mail cho người dùng bằng mã thông báo đặt lại.
  4. Người dùng truy cập trang đặt lại mật khẩu bằng mã thông báo đặt lại trong chuỗi truy vấn.
  5. Kiểm tra cơ sở dữ liệu để xem người dùng được liên kết với mã thông báo đặt lại và nếu thời gian hết hạn không được chuyển.
  6. Nếu mọi thứ kiểm tra, cho phép người dùng đặt lại mật khẩu và xóa mã thông báo đặt lại khỏi cơ sở dữ liệu.

Dường như có nhiều nhầm lẫn về việc tạo mã thông báo đặt lại (hoặc bất kỳ mã nào bạn muốn gọi). Vui lòng đọc câu trả lời tôi đã liên kết và không phát minh lại bánh xe bằng băm và hạt yếu.

+0

Xin chào, đây là những gì tôi cần. tks rất nhiều !! chúc mừng !! – nuttynibbles

+5

khuyến nghị bổ sung: luôn băm mật khẩu đặt lại trước khi lưu vào cơ sở dữ liệu vì nó cũng có thể được sử dụng tạm thời làm mật khẩu người dùng (nghĩa là nó có thể cấp quyền truy cập vào tài khoản người dùng giống như mật khẩu người dùng thông thường). – tigrou

+0

Trong câu trả lời này, bạn nói "tạo một mật khẩu đặt lại ngẫu nhiên duy nhất". Đây là cách tiếp cận không chính xác hoặc thuật ngữ không chính xác. Nếu tôi yêu cầu một mật khẩu bị quên - với địa chỉ email của bạn-, nó sẽ gửi cho bạn một email, với một chuỗi ngẫu nhiên (còn gọi là nonce hoặc token) nhưng mật khẩu hiện tại của bạn sẽ tiếp tục hoạt động! Điều này ngăn cản tôi từ chối dịch vụ của bạn chỉ bằng cách biết tên người dùng hoặc email tài khoản của bạn. Vì vậy, không, không bao giờ tạo ra một mật khẩu ngẫu nhiên thực sự cho người sử dụng, nó không phải là một cách tiếp cận tốt. Chỉ tạo một mã thông báo ngẫu nhiên. – Kzqai

0

1) Để tạo băm duy nhất, kết hợp thời gian hiện tại, id người dùng và một số muối (văn bản). Ví dụ: nếu trang web của bạn là mysite.com, thì hãy sử dụng mã này:

$hash = md5(time() . $userid . 'mysite'); 

Điều này sẽ tạo ra một hàm băm tốt đẹp.

2) Có, lưu trữ trong cơ sở dữ liệu.
3) Có, miễn là bạn hết hạn băm sau một khoảng thời gian cố định, nó sẽ được bảo mật.
4) Không, tạo mật khẩu một lần thường làm phiền người dùng.

+2

Không, nó sẽ không phải vì nó có thể dự đoán được. – Artefacto

+0

Nếu anh ta thay đổi muối đáng kể, thì nó sẽ không thể đoán trước được. Nó không cần thiết để sử dụng 'mysite' chính xác. – shamittomar

+0

Xin chào tất cả, Cảm ơn bạn đã phản hồi rất nhanh. Tôi sẽ tiếp tục với phương pháp cơ sở dữ liệu =) – nuttynibbles

3

Chỉ cần sử dụng một số hàm băm với ID của người dùng, muối của người dùng (bạn Muối mật khẩu của người dùng, phải không?) Và dữ liệu giả ngẫu nhiên nên được OK:

$pwd_reset_hash = hash ('sha256' , $user_id . $user_salt, uniqid("",true));

Lưu trữ nó trong DB (cùng với thời điểm đề nghị) là nút reset cho người dùng này

user_id pwd_reset_hash time_requested 
=========================================== 
123  ae12a45232... 2010-08-24 18:05 

Khi người dùng cố gắng sử dụng nó, hãy kiểm tra hash phù hợp với người dùng và rằng thời gian là gần đây (ví dụ: "thiết lập lại mã có giá trị trong 3 giờ "hoặc một cái gì đó như thế)

xóa nó khỏi DB khi được sử dụng hoặc hết hạn

+2

Tôi khuyên bạn nên chống lại điều này. Nó không tệ như 'time()', nhưng nó vẫn không an toàn. Kẻ tấn công đo độ trễ giữa anh ta và máy chủ có thể đoán băm ít nhất 1 mỗi 20-50 lần. – Artefacto

+0

Ít nhất sử dụng ['uniqid()'] (http://us.php.net/manual/en/function.uniqid.php) thay cho microtime ... – ircmaxell

+0

Xin chào cả hai, tôi hiểu microtime có thể được sử dụng. Nhưng hãy nói rằng nếu tôi đã làm một mô-đun mật khẩu yêu cầu. Người dùng cung cấp email hợp lệ của họ và hệ thống sẽ gửi một email có liên kết xác nhận với chuỗi truy vấn chứa userid và mã băm. khi người dùng nhận được email và nhấp vào liên kết xác nhận, hệ thống sẽ đưa họ đến trang tương ứng và xác thực hàm băm chính xác? để kiểm tra hash này một lần nữa, làm thế nào tôi có thể tạo ra cùng một hash bằng cách sử dụng microtime ?? – nuttynibbles

1

Cách để thực sự tạo ra một số loại điều ngẫu nhiên và lưu trữ nó trong cơ sở dữ liệu. Ngay khi mật khẩu được thay đổi, bạn xóa bản ghi liên quan khỏi bảng để không thể sử dụng lại liên kết.

  • Gửi url cho người dùng, bao gồm cả "mã thông báo".
  • Nếu liên kết được truy cập, hãy kiểm tra xem mã thông báo có tồn tại hay không, cho phép người dùng thay đổi mật khẩu
  • Xóa mã thông báo khỏi cơ sở dữ liệu.

Như đã nói trong các phản hồi khác, thực hiện một SHA1 hoặc MD5 của userid, kết hợp với microtime và một số chuỗi muối thường là đặt cược an toàn.

+0

Xin chào Blizz, tôi đoán việc lưu trữ trong cơ sở dữ liệu là một cách để đi. Cảm ơn blizz – nuttynibbles

+0

1) muối sẽ tốt hơn đủ lớn để nó không thể được đoán bởi một số băm thông qua lực lượng vũ phu 2) Có khó sử dụng 'mt_rand' mỗi lần? Có một hàm trong PHP để tạo ra các số ngẫu nhiên an toàn mã hóa, tại sao bạn lại phát minh ra bánh xe tạo ra một trình tạo chuỗi ngẫu nhiên "tự tạo" với một băm mật mã yếu như MD5 gieo bởi các hạt yếu như 'microtime' ... – Artefacto

+0

Không ai nói rằng bạn không thể kết hợp tất cả những thứ đó. Tôi thường lấy userId, 2 số ngẫu nhiên, microtime và một số chuỗi ngẫu nhiên. – Blizz

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