স্বীকৃত উত্তরের পূর্ববর্তী সংস্করণটি md5(uniqid(mt_rand(), true))
অনিরাপদ এবং কেবলমাত্র প্রায় 2 ^ 60 সম্ভাব্য আউটপুট সরবরাহ করে - স্বল্প বাজেটের আক্রমণকারীর জন্য প্রায় এক সপ্তাহের সময় ধরে নিরপেক্ষ বাহিনীর অনুসন্ধানের সীমার মধ্যে:
যেহেতু একটি 56-বিট ডিইএস কী প্রায় 24 ঘন্টার মধ্যে নৃশংসভাবে জোর করা যেতে পারে , এবং একটি গড় ক্ষেত্রে প্রায় 59 বিট এনট্রপি থাকবে, তাই আমরা 2 ^ 59/2 ^ 56 = প্রায় 8 দিনের জন্য গণনা করতে পারি। এই টোকেন যাচাইকরণ কীভাবে বাস্তবায়িত হয় তার উপর নির্ভর করে, কার্যকরভাবে সময় সম্পর্কিত তথ্য ফাঁস এবং বৈধ পুনরায় সেট টোকেনের প্রথম এন বাইটগুলি নির্ধারণ করা সম্ভব হতে পারে ।
যেহেতু প্রশ্নটি "সেরা অনুশীলনগুলি" সম্পর্কে এবং এর সাথে খোলে ...
আমি ভুলে যাওয়া পাসওয়ার্ডের জন্য সনাক্তকারী তৈরি করতে চাই
... আমরা অনুমান করতে পারি যে এই টোকেনটির অন্তর্নিহিত সুরক্ষা প্রয়োজনীয়তা রয়েছে। এবং যখন আপনি কোনও এলোমেলো সংখ্যার জেনারেটরে সুরক্ষা প্রয়োজনীয়তা যুক্ত করেন, সর্বাধিক অনুশীলন হ'ল সর্বদা ক্রিপ্টোগ্রাফিকভাবে সুরক্ষিত সিউডোর্যান্ডম নম্বর জেনারেটর (সংক্ষেপিত সিএসপিআরএনজি) ব্যবহার করা।
একটি সিএসপিআরএনজি ব্যবহার করে
পিএইচপি 7 এ, আপনি ব্যবহার করতে পারেন bin2hex(random_bytes($n))
(যেখানে $n
15 এর চেয়ে বেশি পূর্ণসংখ্যা রয়েছে)।
পিএইচপি 5 এ, আপনি random_compat
একই এপিআই প্রকাশ করতে ব্যবহার করতে পারেন ।
বিকল্পভাবে, bin2hex(mcrypt_create_iv($n, MCRYPT_DEV_URANDOM))
আপনি ext/mcrypt
ইনস্টল করা থাকলে। আর একটি ভাল ওয়ান-লাইনার bin2hex(openssl_random_pseudo_bytes($n))
।
মূল্যায়নকারী থেকে চেহারা আলাদা করা
আমার পিএইচপি-র সুরক্ষিত "আমাকে মনে রাখুন" কুকিগুলিতে আমার পূর্ববর্তী কাজ থেকে সরে আসা , পূর্বোক্ত সময় লিক (সাধারণত ডাটাবেস ক্যোয়ারী দ্বারা প্রবর্তিত) প্রশমিত করার একমাত্র কার্যকর উপায় হ'ল বৈধতা থেকে লুককে আলাদা করা।
আপনার টেবিলটি যদি এইরকম লাগে (মাইএসকিউএল) ...
CREATE TABLE account_recovery (
id INTEGER(11) UNSIGNED NOT NULL AUTO_INCREMENT
userid INTEGER(11) UNSIGNED NOT NULL,
token CHAR(64),
expires DATETIME,
PRIMARY KEY(id)
);
... আপনাকে আরও একটি কলাম যুক্ত করতে হবে selector
, এর মতো:
CREATE TABLE account_recovery (
id INTEGER(11) UNSIGNED NOT NULL AUTO_INCREMENT
userid INTEGER(11) UNSIGNED NOT NULL,
selector CHAR(16),
token CHAR(64),
expires DATETIME,
PRIMARY KEY(id),
KEY(selector)
);
একটি সিএসপিআরএনজি ব্যবহার করুন যখন কোনও পাসওয়ার্ড পুনরায় সেট করার টোকেন জারি করা হয়, তখন ব্যবহারকারীকে উভয় মান প্রেরণ করুন, নির্বাচক এবং ডাটাবেসে র্যান্ডম টোকেনের একটি SHA-256 হ্যাশ সংরক্ষণ করুন। নির্বাচকটি হ্যাশ এবং ব্যবহারকারী আইডি দখল করতে ব্যবহার করুন, ব্যবহারকারীর ডাটাবেজে সংরক্ষিত থাকা টোকেনটির SHA-256 হ্যাশ গণনা করুন hash_equals()
।
উদাহরণ কোড
পিডিও দিয়ে পিএইচপি 7 (বা 5.6 এলোমেলো_কম্প্যাট সহ) একটি রিসেট টোকন তৈরি করা:
$selector = bin2hex(random_bytes(8));
$token = random_bytes(32);
$urlToEmail = 'http://example.com/reset.php?'.http_build_query([
'selector' => $selector,
'validator' => bin2hex($token)
]);
$expires = new DateTime('NOW');
$expires->add(new DateInterval('PT01H'));
$stmt = $pdo->prepare("INSERT INTO account_recovery (userid, selector, token, expires) VALUES (:userid, :selector, :token, :expires);");
$stmt->execute([
'userid' => $userId,
'selector' => $selector,
'token' => hash('sha256', $token),
'expires' => $expires->format('Y-m-d\TH:i:s')
]);
ব্যবহারকারী দ্বারা সরবরাহিত রিসেট টোকন যাচাই করা হচ্ছে:
$stmt = $pdo->prepare("SELECT * FROM account_recovery WHERE selector = ? AND expires >= NOW()");
$stmt->execute([$selector]);
$results = $stmt->fetchAll(PDO::FETCH_ASSOC);
if (!empty($results)) {
$calc = hash('sha256', hex2bin($validator));
if (hash_equals($calc, $results[0]['token'])) {
}
}
এই কোড স্নিপেটগুলি সম্পূর্ণ সমাধান নয় (আমি ইনপুট বৈধতা এবং কাঠামোর একীকরণগুলি এচু করেছি) তবে তাদের কী করা উচিত তার উদাহরণ হিসাবে পরিবেশন করা উচিত।