۱ مهران
تفاوت بین password و hash و token
جامعه پی اچ پی ایجاد شده در ۲۸ مرداد ۱۴۰۲

سلام من فرق ایتها را نفهمیدم میشه توضیح بدین چه فرقی بین این سه مورد هست ؟ ایا hash همون password هستش ؟ و اگر بخواهیم پسورد را به صورت پسورد یکبار مصرف با sms ارسال کنیم به چه صورته ؟

سلام،

Password: رشته ای که کاربر برای خودش انتخاب کرده (رمز عبور)

کاربر مثلاً رمز عبورشو گذاشته 123456


Hash: الگوریتم‌های رمزنگاری مختلفی برای هش داریم. تابع هش به این صورت عمل میکنه، یک رشته رو بهش میدیم و رشته رو تبدیل به هش میکنه که از طریق این هش، تابعی وجود نداره که عبارت هش شده رو بشه برگردوند به عبارت اولیه اش.

مثلا رمز عبور 123456 رو به تابع MD5 میدیم، هش این عبارت میشه:

echo md5('123456');
// e10adc3949ba59abbe56e057f20f883e

حالا آیا تابعی وجود دارد که e10adc3949ba59abbe56e057f20f883e رو بدیم و برسیم به 123456؟ خیر.

بخاطر همین میگن Hash برگشت پذیر نیست و برای چنین مصارف امنیتی مثل پسورد استفاده میشود.

مورد دیگر هم اینکه md5('123456') جوابش همیشه e10adc3949ba59abbe56e057f20f883e خواهد بود.(یعنی یک عبارت هر سری یک هش جدید ندارد)

به تابع md5 چه یک رشته 3 کاراکتری مثل 123 بدیم چه محتوای یک کتاب، خروجی اش رشته ای 32 کاراکتری خواهد بود.

اینهم موضوع Hash است که برای اینکه پسورد کاربران مشخص نباشد، با الگوریتم‌های رمزنگاری هش میشوند.

الگوریتم‌های هش مختلفی وجود دارد که هر کدام مزایا و معایبی دارد که میتونید در موردشون تحقیق کنید که ملاک انتخاب یک الگوریتم برای پسورد امن چیست. چرا میگن md5 امنیت پایینی دارد و دیگر برای پسورد استفاده نمیشود و ...

نکته: الگوریتم Bcrypt برای پسورد بسیار مناسب است و از توابع password_hash و password_verify استفاده میشود. (PASSWORD_DEFAULT همین الگوریتم است.) الگوریتم‌های ARGON2I و ARGON2ID هم بعد بسیار قدرتمند هستند.

// BCRYPT
$password = "secret";
$hashedPassword = password_hash($password, PASSWORD_BCRYPT);
// PASSWORD_ARGON2I
$password = "secret";
$hashedPassword = password_hash($password, PASSWORD_ARGON2I);


Token: جاهای مختلف و در کاربردهای گوناگون اسم توکن رو میشنویم. ولی در اینجا توکن یک رشته است که با هر الگوریتمی که مد نظر برنامه نویس است میتونه تولید بشه. مهم این است که توکن منحصر به فرد(یونیک) باشد و قراره این توکن یکبار مصرف باشه و براساس این توکن درستی و مجوز یک operation صادر بشه. مثلاً در فرم‌ها هم ما توکنی بعنوان توکن CSRF داریم تا از چنین حمله ای در فرم‌ها جلوگیری شود. توکن در قسمت‌های مختلفی میتونه استفاده بشه.

یک مثال ساده برای تولید توکن اینست که تابعی بنویسید که فرضاً 15 کاراکتر رندوم درکنار هم تولید کنه یا از microtime استفاده کنید و با md5 تبدیل به رشته 32 کاراکتری شود و ... (از لحاظ امنیتی توکنی که generate میشود حائز اهمیت است و نباید قابل حدس و تولید باشد بنابراین الگوریتم ساخت مهم است)

تابع تولید Token:

function generateToken($length = 32){
    return bin2hex(random_bytes($length));
}
$token = generateToken();
  • حتما باید یونیک باشد و در یک لحظه اگر چند توکن تولید شد هر تعداد تولید شده متمایز و یونیک باشد.

از دیگر کاربردهای این توکن برای ساخت لینک فعال سازی اکانت یا فراموشی پسورد که توکنی ساخته شود و در لینک قرار بگیرد و برای کاربر ایمیل شود.

کاربر روی لینک که کلیک کند در سمت سرور توکن چک میشود و عملیات ولیدیت و ... و همچنین منقضی میشود.


پسورد یکبار مصرف هم با فیلد پسورد اصلی متفاوت است. پسورد یکبار مصرف فیلد جدایی خواهد داشت، تولید میشود و به کاربر sms میشود و کاربر در قسمت مربوطه وارد میکند و در سمت سرور چک میشود.

این کلیت ماجراست که جزئیات بیشتری خواهند داشت ولی با انجام پروژه و مطالعه بصورت کامل دستتون میاد.

محسن موحد ۲۸ مرداد ۱۴۰۲، ۱۷:۱۸