روز برنامه‌نویس مبارک 🤩🎉 از هدایای روز برنامه‌نویس جا نمونی ⌛
۰ ثانیه
۰ دقیقه
۰ ساعت
۸ علی
تابع random_bytes
جامعه پی اچ پی ایجاد شده در ۱۰ بهمن ۱۴۰۰

سلام

یه سوال داشتم درمورد تابع random_bytes تویه manual php این تابع رو به صورت زیر تعریف کرده

Generates cryptographically secure pseudo-random bytes

منظور از cryptographically secure pseudo-random bytes چیه؟ تابع random_bytes که یه سری byte تصادفی ایجاد میکنه اما منظور از cryptographically secure چیه؟ یعنی این تابع بایت‌ها رو رمزگذاری هم میکنه ؟

سلام.

این الگوریتم برای تولید رشته‌های تصادفی امن هست و شما میتونید توی رمزنگاری و داده‌های حساس استفاده کنید.

فرض کنید کاربر پسوردشو فراموش کرده و شما قراره پسورد جدید رو به ایمیلش ارسال کنید؛ شاید برای تولید یک رشته ی تصادفی سمت توابعی مثل mt_rand برید که امنیت لازمو برای اینکار نداره و الگوریتمش از لحاظ یک رشته ی رندوم امن نیست برای همین منظور میتونید از random_bytes و random_int استفاده کنید. این توابع بصورت واقعی رشته رندوم تولید میکنند.

برای random_int مثالی اومده داخل خود php.net برای بر زدن کارتها و ...

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

اگر random_bytes رو خواستید بصورت مستقیم در دیتابیس ذخیره کنید، چون این رشته از بایت‌های رندوم تشکیل شده میتونید تبدیل کنید به hex یا binary:

function random_binary($bytes) {
  return base_convert(bin2hex(random_bytes($bytes)), 16, 2);
}
echo random_binary(1);
// 10000011
محسن موحد ۱۰ بهمن ۱۴۰۰، ۲۳:۱۲

ممنون از پاسختون


cryptographically secure pseudo-random integers

cryptographically secure pseudo-random bytes

cryptographically secure pseudo-random data


  1. پس منظور از عبارت‌های بالا اینه که داده‌های تصادفی تولید شده به اندازه کافی امن هستند تا برای اهداف رمزگذاری استفاده شوند درسته؟


2. و ی سوال دیگه ما تو برنامه نویسی وقتی از رشته صحبت میکنیم منظورمون مجموعه ای از کاراکترها مثل hajwddfawe هست. گفته میشه که متد random_byte یک رشته تصادفی تولید میکنه. ولی متد random_byte خروجی مثل hajwddfawe تولید نمیکنه


واسه کامپیوتر یک رشته یعنی یک توالی از صفر و یک‌ها حالا وقتی گفته میشه متد random_byte یک رشته برمیگردونه درواقع منظورش یک توالی random از صفر و یک هاست که واسه کامپیوتر معنی داره و این رشته لزومن از کاراکترهایی که ما میشناسیم تشکیل نشده. درواقع این متد میاد یک رشته واسه کامپیوتر درست میکنه و بخاطر همین هم امن محسوب میشه


درست متوجه شدم؟


علی ۱۱ بهمن ۱۴۰۰، ۰۶:۵۸

۱. درسته.

۲. ببینید هر داده ای در سیستم کامپیوتری از بیت‌های متوالی صفرو یک تشکیل شده که به این موضوع اشراف دارید. حالا این بیت‌های صفرو یک در هر سیستم فایلی خروجی متفاوتی داره، برای مثال اگر بیت‌های یک تصویرو در یک تکست ادیتور باز کنید، کاراکتر‌های ناخوانا چاپ میشود، چون الگوریتم تکست فایل متفاوته، یعنی هر نوع داده ای باید با نرم افزار مخصوص به خودش باز بشه.

ما دو نوع فایل داریم، باینری فایل و تکست فایل.

محسن موحد ۱۱ بهمن ۱۴۰۰، ۱۰:۳۷

منظورتون از بخش 2 رو متوجه نشدم؟

اون سوالی که بالا در بخش 2 مطرح کردمو با یه مثال توضیح میدم تا بهتر منظورمو متوجه بشید


بخش اول : شما فرض کن ما میخواهیم یک کلید بسازیم واسه رمز کردن یک متن. مشخصه که باید از یک کلید ایمن استفاده کنیم که به سادگی قابل حدس نباشه.


اگه من بیام از یک رشته 2 بایتی (مثل ab) که از حروف انگلیسی تشکیل شده به عنوان کلید استفاده کنم. احتمال پیدا کردن همچین رشته‌ای برابر با 1/676


ولی اگه از یک رشته بیتی (مثل 01010010 10100010) به عنوان کلید استفاده کنیم که این رشته 2 بایت هست. احتمال پیدا کردن همچین رشته ای برابر با 1/65536. حالا کاری که تابع random_byte میکنه اینه که به صورت تصادفی یک رشته بیتی با طول دلخواه برای ما ایجاد میکنه و چون احتمال حدس زدن این کلید خیلی کمه به همین خاطر یک کلید امن محسوب میشه که میتونیم برای اهداف رمزگذاری ازش استفاده کنیم


بخش دوم : و بنظرم چون خروجی تابع random_byte یک رشته بیتی هست به همین خاطر هم وقتی echo میشه به صورت کارکترهای ناخوانا نمایش داده میشه. (ممنون میشم نظرتون درمورد دو بخش بگین)

علی ۱۱ بهمن ۱۴۰۰، ۱۲:۱۷

بین بیت‌های رندوم و بیت‌های حروف انگلیسی یا اعدا یا بقیه ی نشانه گذاری‌های معنی دار تفاوتی وجود نداره جز اینکه بیت‌های این کاراکترها با توجه به انکدینگ‌های تعریف شده، به حروف انگلیسی یا... در می‌آیند. ممکنه random_bytes بیت‌های پشت سرهمی بصورت رندوم تولید کنه که نشان دهنده ی یک حرف انگلیسی باشه. علت اینکه به این تابع امن گفته میشه بخاطر نوع الگوریتمش هست وگرنه در زبان php الگوریتم‌های دیگری برای رندوم وجود داره.

تابع دیگری هم وجود داره random_int که طبق گفته php.net امن هست و خروجی این تابع از اعداد تشکیل شده.


محسن موحد ۱۲ بهمن ۱۴۰۰، ۱۰:۳۵

نکته ی دیگه ای رو هم اضافه کنم، اگر توکن csrf رو ببینید، متوجه منظور من میشید، این توکن تشکیل شده از کاراکترهای اسکی که با تابع base64 انکد شده. برای تولید این توکن امنیتی میتونیم از این تابع کمک بگیریم. بنابراین موضوع امنیت این تابع، نوع کاراکترش نیست، نوع رندوم بودنش هست.

محسن موحد ۱۲ بهمن ۱۴۰۰، ۱۰:۴۲

بله کاملا موافقم


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


شما فرض کن ما میخواهیم یک کلید یک بایتی بسازیم


هر حرف انگلیسی معادل یک بایت هست اگه ما از حرف A به عنوان کلید استفاده کنیم یعنی از بین 26 (تعداد حروف انگلیسی) بایت مختلف اومدیم یک بایت رو به عنوان کلید در نظر گرفتیم


اما با استفاده از 8 بیت میتونیم 256 بایت مختلف تولید کنیم حالا اگه بیاییم از یک بابت تصادفی به عنوان کلید استفاده کنیم درواقع ما داریم یک بایت از بین 256 بایت مختلف انتخاب میکنیم


این مشخصه که پیدا کردن یک بایت از بین 26 بایت مختلف اسون‌تر از پیدا کردن یک بایت از بین 256 بایت مختلفه. درنتیجه استفاده از یک بایت تصادفی امن‌تر هست چون احتمال پیدا کردنش کمتره


پس اون امنیتی که ازش صحبت میشه از اینجا نشاُت میگیره. موافقید؟


کار تابع random_bytes اینه که با استفاده از الگوریتمی واسش نوشته شده میاد بایت کاملا تصادفی برای ما ایجاد میکنه حالا این بایت تصادفی ممکنه نشاندهنده یه کاراکتر معنادار باشه و ممکنه نباشه

علی ۱۲ بهمن ۱۴۰۰، ۱۱:۳۱

بله توضیحات شما درسته.

بهترین پاسخ
محسن موحد ۱۲ بهمن ۱۴۰۰، ۱۳:۲۵