از طریق منوی جستجو مطلب مورد نظر خود در وبلاگ را به سرعت پیدا کنید
هش کردن پسوردها در پایتون با BCrypt
سرفصلهای مطلب
معرفی
ذخیره رمزهای عبور ایمن باید برای هر مهندس معتبری ضروری باشد. رمزهای عبور متن ساده بسیار ناامن هستند – حتی نباید به فکر ذخیره آنها در قالب ساده باشید. همین که کسی سود می برد کافی است چشم انداز امتیازات روی یک پایگاه داده برای کل پایگاه کاربر به خطر بیافتد.
رمزهای عبور باید در یک پایگاه داده به روشی امن و در عین حال قابل مدیریت ذخیره شوند.
شما همیشه باید فرض کنید که پایگاه داده شما خواهد بود به خطر افتاده و تمام اقدامات احتیاطی لازم را برای جلوگیری از سوء استفاده هر کسی که می تواند داده های شما را در اختیار داشته باشد، انجام دهد. این امر به ویژه برای پایگاههای دادهای که اعتبار ورود کاربران یا سایر دادههای حساس را ذخیره میکنند صادق است.
علاوه بر این – این یک مسئله رفتار اخلاقی است. اگر یک کاربر برای وب سایت شما ثبت نام کند – آیا باید بتوانید کلمه عبور خود را کلمه عبور پیدا کنید؟ رمز عبور اغلب استفاده می شود روی چندین وبسایت، حاوی اطلاعات شخصی هستند و/یا میتوانند طرفی از کاربر را که نمیخواهند بهصورت عمومی منتشر کنند، افشا کنند. هیچ کدام شما و نه الف بازیگر بدخواه باید قادر به خواندن رمز عبور متن ساده در هر نقطه باشد. به همین دلیل است که وبسایتها نمیتوانند وقتی رمز عبور خود را فراموش کردید برای شما ایمیل کنند – آنها آن را نمیدانند. باید ریستش کنی
هش کردن رمزهای عبور یک روش ارزان، ایمن و استاندارد است که رمزهای عبور را هم از وب مستر و هم از عوامل مخرب محافظت می کند.
برای جلوگیری از سوء استفاده آشکار از اعتبارنامه ورود، باید همیشه هش رمزهای عبور قبل از ذخیره آنها در پایگاه داده این ساده ترین و در عین حال موثرترین راه برای جلوگیری از استفاده غیرمجاز از رمزهای عبور ذخیره شده در پایگاه داده شما است. حتی اگر شخصی اعتبار ورود کاربران را به دست آورد، آن اطلاعات را نمی توان به هیچ شکل یا شکلی استفاده کرد، زیرا قالب برای انسان قابل خواندن نیست و از نظر محاسباتی شکستن آن سخت است.
در این راهنما، روش هش رمزهای عبور خود را در پایتون با استفاده از BCrypt توضیح خواهیم داد. هش کردن چیست، هشها چگونه مقایسه میشوند، “salting” چگونه کار میکند و چگونه هش کردن رمزهای عبور را ایمن میکند.
هش کردن رمز عبور چیست؟
در ابتدایی ترین شکل خود، هش کردن به تبدیل یک رشته به رشته دیگر اشاره دارد (که به آن a نیز می گویند هش) با استفاده از a تابع هش. صرف نظر از اندازه یک رشته ورودی، هش یک اندازه ثابت خواهد داشت که در یک از پیش تعریف شده است. الگوریتم هش خود هدف این است که هش چیزی شبیه رشته ورودی نباشد و هر تغییری در رشته ورودی باعث ایجاد تغییر در هش شود.
علاوه بر این – توابع هش، ورودی هش در a یک طرفه روش. این یک سفر رفت و برگشت نیست و رمز عبور هش شده قابل بازگشایی نیست. تنها راه برای بررسی اینکه آیا رمز عبور ورودی با رمز عبور موجود در پایگاه داده مطابقت دارد یا خیر این است هش رمز ورود را نیز، و سپس هش ها را مقایسه کنید. به این ترتیب، ما نیازی به دانستن رمز عبور واقعی نداریم تا مطمئن شویم که آیا رمز عبور با رمز عبور موجود در پایگاه داده مطابقت دارد یا خیر.
توجه داشته باشید: در این راهنما از این اصطلاح استفاده خواهیم کرد “عملکرد هش” برای یک تابع ریاضی که برای محاسبه هش با اندازه ثابت استفاده می شود روی رشته ورودی (توابع هش محبوب شامل SHA256، SHA1، MD5، CRC32، BCrypt و غیره). آ “الگوریتم هش” به کل اشاره دارد process هش کردن، شامل نه تنها یک تابع هش مورد استفاده، بلکه بسیاری از پارامترهای دیگر که می توانند در طول process از هش کردن
هر وقت چیزی مانند "myPwd"
در الگوریتم هش کردن، دقیقا همان خروجی را دریافت خواهید کرد. اما اگر تغییر کنی "myPwd"
حتی اندکی، خروجی غیرقابل تشخیص تغییر خواهد کرد.
این تضمین می کند که حتی رشته های ورودی مشابه هش های کاملاً متفاوتی تولید می کنند. اگر گذرواژههای مشابه همان هشها را تولید میکردند – کرک یکی رمز عبور ساده می تواند منجر به ایجاد یک جدول جستجو برای کاراکترهای دیگر شود. از طرف دیگر، از آنجایی که یک ورودی یکسان همیشه خروجی یکسانی را به همراه دارد، هش کردن بسیار زیبا است قابل پیش بینی.
پیش بینی به راحتی قابل بهره برداری است.
اگر کسی بداند که از چه تابع هش برای هش کردن یک رمز عبور خاص استفاده شده است (و لیست زیادی از توابع هش در حال استفاده وجود ندارد)، می تواند آن را با حدس زدن همه رمزهای عبور ممکن، هش کردن آنها با همان تابع هش و مقایسه به دست آمده، شکست دهد. هش رمز عبوری که می خواهند آن را بشکنند. به این نوع حمله a گفته می شود حمله بی رحمانه و این حمله برای رمزهای عبور ساده بسیار خوب عمل می کرد، مانند password123
، 12345678
، و غیره.
ساده ترین راه برای جلوگیری از حملات brute-force استفاده از یک تابع هش است که محاسبه آن نسبتاً کند است. به این ترتیب حمله brute-force برای محاسبه همه هشهای ممکن زمان زیادی میبرد که حتی ارزش تلاش برای انجام آن را ندارد.
علاوه بر این، اکثر برنامههای کاربردی وب پس از وارد کردن تعداد معینی از رمزهای عبور نادرست، «تایماوتهای» داخلی دارند که باعث میشود در صورتی که فردی بخواهد رمز عبور را از طریق یک رابط کاربری کنترلشده اعمال کند، حدس زدن brute-force غیرقابل اجرا میشود، هرچند، این مورد برقرار نیست. اگر شخصی یک کپی محلی از رمز عبور هش شده به دست آورد.
نمک در رمز عبور چیست؟
همانطور که رمزنگاری، قیمت هر محاسبات و فناوری پیشرفت می کند – فقط انتخاب یک تابع هش مناسب نیست کاملا به اندازه کافی برای ایمن کردن رمزهای عبور ذخیره شده در یک پایگاه داده. در برخی موارد، حتی یک عملکرد هش عالی نمی تواند از حمله جلوگیری کند. بنابراین، توصیه می شود اقدامات احتیاطی بیشتری انجام دهید تا شکستن رمزهای عبور ذخیره شده حتی دشوارتر شود.
مشکل هش کردن این است که خروجی (یعنی هش) همیشه برای همان ورودی یکسان است. این باعث می شود هشدار قابل پیش بینی ، در نتیجه آسیب پذیر باشد. شما می توانید با عبور یک رشته تصادفی اضافی در کنار رشته ورودی هنگام اجرای هش، آن را حل کنید. این تضمین میکند که هشسازی هر بار که رشتهای مشابه ورودی دریافت میکند، دیگر خروجی مشابهی تولید نمیکند.
آن رشته شبه تصادفی با طول ثابت که هنگام اجرای هش در کنار رشته ورودی ارسال می شود، نامیده می شود. نمک. هر بار که می خواهید رمز عبور را در پایگاه داده ذخیره کنید، یک salt تصادفی جدید ایجاد می شود و در کنار رمز عبور به تابع هش ارسال می شود. در نتیجه، حتی اگر دو کاربر رمز عبور یکسانی داشته باشند، رکورد آن در یک پایگاه داده کاملاً متفاوت خواهد بود.
به یاد داشته باشید که اضافه کردن یک شخصیت واحد به پایان یک رشته قبل از هش کردن، هش را به طور کامل تغییر می دهد.
نمکی که برای تولید رمز عبور استفاده میشود، بهطور جداگانه ذخیره میشود، و به هر ورودی جدیدی که باید هش شود اضافه میشود و با هش ذخیرهشده در پایگاه داده مقایسه میشود، این اطمینان را میدهد که حتی با افزودن عناصر تصادفی – کاربر میتواند با استفاده از رمز عبور مربوطه خود وارد شود. . هدف از Salting این نیست که شکستن یک رمز عبور از نظر محاسباتی بسیار دشوارتر شود – بلکه جلوگیری از یافتن شباهت بین رشته های هش شده و جلوگیری از شکستن مهاجم است. چندگانه پسوردها اگر یکسان باشند
از طریق نمک زدن – عملیات بسیار پرهزینه محاسباتی در یک نمونه محلی سازی شده و باید برای هر رمز عبور در پایگاه داده تکرار شود.، جلوی یک آبشار از امنیت شکسته را می گیرد.
خوشبختانه – کل این منطق معمولاً توسط چارچوبهای امنیتی و ماژولهایی که میتوانیم به راحتی در کد استفاده کنیم، انتزاع میشود.
BCrypt چیست؟
BCrypt یک الگوریتم هش رمز عبور است که با تمام اقدامات احتیاطی که در ذهن داشته ایم طراحی شده است. این الگوریتم به عنوان الگوریتم پیشفرض هش رمز عبور در OpenBSD، یک سیستم عامل مبتنی بر امنیت منبع باز، استفاده میشود و گستردهترین الگوریتم هش کردن تا به امروز است.
BCrypt نسبتا امن در نظر گرفته می شود. تابع هش آن است روی الگوریتم Blowfish (رمز).، نمک زدایی و سرعت محاسبات تطبیقی را پیاده سازی می کند. سرعت تطبیقی به توانایی افزایش پیچیدگی محاسبه مقدار هش اشاره دارد که در آینده الگوریتم را اثبات می کند. بدون توجه به افزایش سرعت محاسباتی سخت افزار، به اندازه کافی کند است تا از حملات brute-force جلوگیری کند.
BCrypt به طور گسترده در اکثر زبان های رایج پشتیبانی و پیاده سازی می شود. پیاده سازی های عمومی برای جاوا، جاوا اسکریپت، C، C++، C#، Go، Perl، PHP و غیره وجود دارد. در این راهنما، ما این موارد را پوشش خواهیم داد. پیاده سازی پایتون از الگوریتم BCrypt.
روش هش کردن رمز عبور در پایتون با استفاده از BCrypt
این bcrypt
مدول روی PyPi یک پیاده سازی عالی از BCrypt را ارائه می دهد که می توانیم به راحتی از طریق آن نصب کنیم pip
:
$ pip install bcrypt
توجه داشته باشید:
برای اطمینان از نصب تمام وابستگی های مورد نیاز، اسناد رسمی به شما توصیه می کند که دستورات زیر را بر اساس اجرا کنید. روی سیستم عامل انتخابی شما
برای دبیان و اوبونتو:
$ sudo apt-get install build-essential libffi-dev python-dev
برای Fedora و مشتقات RHEL:
$ sudo yum install gcc libffi-devel python-devel
برای آلپاین:
$ apk add --update musl-dev gcc libffi-dev
پس از نصب BCrypt با استفاده از pip
، تو می توانی import آن را به پروژه شما:
import bcrypt
برای هش رمز عبور خود با استفاده از BCrypt، ابتدا باید آن را به آرایه بایت تبدیل کنید. برای رسیدن به آن می توانیم از encode()
روش از string
کلاس! نسخه رشته ای رمز عبوری را که می خواهید هش کنید، با توجه به نوع رمزگذاری خاص، در یک آرایه بایتی رمزگذاری می کند و هش کردن با استفاده از BCrypt را ممکن می کند.
بگیریم 'MyPassWord'
به عنوان مثال رمز عبور برای نشان دادن استفاده از BCrypt:
pwd = 'MyPassWord'
bytePwd = pwd.encode('utf-8')
این encode()
متد یک رشته را در برخی از کدگذاری ها (مانند ASCII، UTF-8، و غیره) می گیرد و آن را به یک آرایه مربوطه از بایت ها تبدیل می کند. آرایه بایتی که از یک رشته تشکیل شده است a نامیده می شود رشته b.
توجه داشته باشید: در مثال قبلی، pwd
یک رشته است و bytePwd
یک آرایه بایت است. اما اگر شما print هر دو متغیر، تنها تفاوت قابل مشاهده این است که bytePwd
دارد b
به عنوان پیشوند قبل از مقدار آن – b'myPassword'
. از این رو نام آن نوع آرایه بایت – a رشته b.
در نهایت، می توانید رمز عبور رمزگذاری شده را با استفاده از BCrypt هش کنید:
mySalt = bcrypt.gensalt()
pwd_hash = bcrypt.hashpw(bytePwd, mySalt)
همانطور که می بینید، روش مورد استفاده برای هش در BCrypt است hashpw()
. به دو استدلال نیاز دارد رشته b نمایش رمز عبور و الف نمک. بدیهی است که شما می توانید به صورت دستی نمک ایجاد کنید، اما قطعا استفاده از آن توصیه می شود gensalt()
روش در عوض. این یک روش BCrypt است که به طور خاص برای ایجاد نمک به شیوه ای امن رمزنگاری ایجاد شده است.
توجه داشته باشید: سرعت محاسبات تطبیقی در BCrypt با تنظیم تعدادی تکرار مورد نیاز برای ایجاد نمک به دست می آید. این مقدار به عنوان آرگومان ارسال می شود gensalt()
روش. مقدار پیش فرض 12 است، به این معنی که BCrypt از 2 استفاده می کند12 (4096) تکرار برای تولید نمک. با افزایش مقدار آن آرگومان، تعداد تکرارهای مورد استفاده برای تولید نمک را افزایش میدهید و در نتیجه زمان مورد نیاز برای محاسبه هش را افزایش میدهید.
در حال حاضر hash
نسخه هش شده رمز عبور را ذخیره می کند pwd
. این hash
باید تا حدودی شبیه به:
b'$2b$12$1XCXpgmbzURJvo.bA5m58OSE4qhe6pukgSRMrxI9aNSlePy06FuTi'
خیلی شبیه رمز اصلی نیست، درست است؟ اما اگر مقایسه کنید hash
به رمز عبور اصلی با استفاده از BCrypt’s checkpw()
روش، a را برمی گرداند True
ارزش!
توجه داشته باشید: این checkpw()
روش برای اعتبارسنجی رمزهای عبور هش شده طراحی شده است. رمز عبور ورودی جدید را هش می کند، نمکی را که به طور خودکار ردیابی می کند اضافه می کند و سپس نتایج را با هم مقایسه می کند.
بیایید بررسی کنیم که آیا متن تحت اللفظی است password
یک رمز عبور معتبر برای جدید است hash
ما به تازگی ایجاد کرده ایم:
password = 'MyPassWord'
password = password.encode('utf-8')
print(bcrypt.checkpw(password, pwd_hash))
اجزای یک خروجی BCrypt
همانطور که در مثال قبلی دیدیم، ورودی به BCrypt یک رمز عبور (تا 72 بایت) و یک نمک (با تعداد تکرارهای مرتبط) است و خروجی هش 24 بایتی است.
بیایید تصویر زیر را بررسی کنیم تا درک کنیم که چگونه BCrypt هش تولید شده را می سازد:
این تصویر هش رمز عبور را نشان می دهد، 'MyPassword'
، بنابراین هش کردن بخش قبل را نشان می دهد.
همانطور که قبلاً بحث کردیم، هر بار که با آن تماس می گیرید gensalt()
روش، یک آرایه بایت با اندازه ثابت جدید تولید می کند (نمایش داده شده توسط a رشته b). در این مثال، gensalt()
روش تولید خروجی با علامت گذاری شده است salt
در تصویر بیایید تجزیه کنیم salt
بخش و هر زیربخش جداگانه را توضیح دهید.
این salt
دارای سه زیربخش تقسیم بر $
امضا کردن:
-
نسخه bcrypt
یک شناسه الگوریتم هش ویژه – در این مورد2b
– جدیدترین نسخه الگوریتم BCrypt. -
توان
استدلال ازgensalt()
روش تعداد تکرارهای مورد استفاده برای محاسبه نمک را نشان می دهد. اگر هیچ آرگومانی ارسال نشود، مقدار پیش فرض 12، بنابراین 2 است12 از تکرارها برای محاسبه نمک استفاده می شود. -
نمک تولید شده
آ radix-64 رمزگذاری نمک تولید شده با 22 کاراکتر نشان داده شده است.
پس از آن، BCrypt می چسبد salt
همراه با مقدار هش شده MyPassword
و در نتیجه نهایی را ایجاد می کند hash
از MyPassword
.
توجه داشته باشید: مقدار هش شده از MyPassword
(یا هر رمز عبور دیگری) به رمزگذاری radix-64 از 23 بایت اول هش 24 بایتی اشاره دارد. با 31 کاراکتر نشان داده شده است.
نتیجه
پس از خواندن این مقاله، درک کاملی از روش استفاده از BCrypt برای هش رمز عبور قبل از ذخیره آن در پایگاه داده خواهید داشت. برای اینکه همه چیز را در یک چشم انداز قرار دهیم، اصطلاحات اساسی را در یک مفهوم کلی توضیح داده ایم و سپس آن را توضیح داده ایم. process از هش کردن رمز عبور روی مثال BCrypt
(برچسبها به ترجمه)# python
منتشر شده در 1403-01-06 23:08:03