رنگین کمان در جدول
رنگینکمان در جدول چیست؟ راهنمای ساده و کاربردی Rainbow Table
وقتی نام «رنگینکمان در جدول» را میشنویم، شاید ذهنمان سراغ جدولهای رنگی یا دادههای بصری برود؛ اما در امنیت سایبری، Rainbow Table نام روشی برای پیدا کردن گذرواژه از روی مقدار هششده آن است.
این روش معمولاً زمانی مطرح میشود که پایگاه داده یک سایت، سامانه یا برنامه لو رفته باشد و مهاجم به هش گذرواژهها دسترسی پیدا کند. خود هش مثل متن معمولی قابل خواندن نیست، اما اگر رمز عبور ضعیف باشد و بدون تمهیدات امنیتی مناسب ذخیره شده باشد، جدولهای ازپیشمحاسبهشده میتوانند حدسزدن آن را سریعتر کنند.
برای کاربران ایرانی، این موضوع فقط بحثی دانشگاهی نیست. بسیاری از افراد هنوز از شماره موبایل، تاریخ تولد، نام فرزند، عبارتهایی مثل 123456 یا ترکیب سادهای از نام و سال تولد استفاده میکنند. چنین رمزهایی حتی بدون Rainbow Table هم هدف آسانی هستند.
هش چیست و چه فرقی با رمزنگاری دارد؟
هشکردن، تبدیل یک داده به رشتهای با طول مشخص است. برای نمونه، یک رمز عبور بهصورت مفهومی چنین تغییری میکند:
textpassword123 → 482c811da5d5b4bc6d497ffa98491e38
خروجی، هش نام دارد. در طراحی درست، از روی هش نباید بتوان متن اصلی را بهسادگی به دست آورد. به همین دلیل هش با رمزنگاری فرق دارد؛ در رمزنگاری معمولاً داده با یک کلید رمز میشود و با کلید مناسب دوباره قابل بازیابی است، اما هش برای ساخت یک اثرانگشت دیجیتال طراحی شده است.
البته «یکطرفه بودن» به معنای جادویی و نفوذناپذیر بودن نیست. اگر کسی حدس بزند رمز عبور 123456 بوده، میتواند همان عبارت را هش کند و نتیجه را با هش سرقتشده مقایسه کند. هرچه رمزهای احتمالی کمتر و رایجتر باشند، این آزمون سریعتر جواب میدهد.
Rainbow Table دقیقاً چه کاری انجام میدهد؟
Rainbow Table فهرستی معمولی از رمزها نیست. این روش مجموعهای از محاسبات ازپیشانجامشده را به شکل فشرده نگه میدارد تا جستوجوی هشهای شناختهشده سریعتر شود.
در یک جدول ساده ممکن است ارتباطهای زیادی ذخیره شود:
textرمز عبور ۱ → هش ۱ رمز عبور ۲ → هش ۲ رمز عبور ۳ → هش ۳
ذخیرهکردن همه این جفتها فضای زیادی میخواهد. Rainbow Table برای کاهش حجم، بهجای نگهداری همه نتایج، از زنجیرههای هش استفاده میکند. در این زنجیره، یک رمز به هش تبدیل میشود و سپس یک تابع کاهش، هش را به مقدار احتمالی دیگری تبدیل میکند. این فرایند چند بار تکرار میشود و فقط بخشهایی از زنجیره ذخیره میگردد.
هنگام بررسی یک هش سرقتشده، مهاجم زنجیرههای احتمالی را دوباره محاسبه میکند تا ببیند هش موردنظر در یکی از آنها قرار دارد یا نه. اگر زنجیره پیدا شود، مسیر آن به عقب بازسازی میشود تا رمز احتمالی مشخص شود.
این روش در اصل یک مصالحه میان زمان و حافظه است:
- ذخیرهسازی آن از جدول کامل کمتر است.
- جستوجو از حمله کاملاً خام سریعتر انجام میشود.
- مقداری محاسبه در زمان بررسی لازم دارد.
- برای هر نوع هش و هر مجموعه رمز، جدول جداگانهای لازم است.
پروفسور فیلیپ اوشلین در مقاله معروف خود با عنوان Making a Faster Cryptanalytic Time-Memory Trade-Off که در کنفرانس CRYPTO 2003 منتشر شد، Rainbow Table را بهعنوان بهبودی بر روشهای قدیمیتر مبادله زمان و حافظه معرفی کرد.
چرا جدول را «رنگینکمان» نامیدهاند؟
در روشهای قدیمیتر، زنجیرههای محاسباتی ممکن بود با هم تداخل زیادی داشته باشند. اوشلین با طراحی چند تابع کاهش متفاوت، احتمال تداخل زنجیرهها را کم کرد. این تفاوت را میتوان به استفاده از چند رنگ در مسیرهای جداگانه تشبیه کرد؛ از همینجا نام Rainbow Table شکل گرفت.
این نام به ظاهر رنگی جدول ارتباطی ندارد. یک Rainbow Table واقعی ممکن است در قالب فایلهای فنی ذخیره شود و هیچ رنگی در آن دیده نشود.
یک مثال ساده برای درک روش
فرض کنید سایتی رمز کاربران را با یک الگوریتم هش سریع و بدون Salt ذخیره کرده است. یکی از کاربران رمز Ali1378 را انتخاب کرده و هش آن در پایگاه داده قرار گرفته است.
مهاجم میتواند از قبل تعداد زیادی عبارت رایج را پردازش کرده باشد:
textAli1376 Ali1377 Ali1378 Ali1379 Ali1380
اگر هش رمز Ali1378 در محاسبات آماده وجود داشته باشد، مهاجم بهجای آزمودن همه حالتها از صفر، مستقیماً از نتیجه قبلی استفاده میکند.
این اتفاق زمانی خطرناکتر میشود که چند کاربر یک رمز یکسان داشته باشند. اگر سیستم برای همه آنها دقیقاً یک هش ذخیره کرده باشد، مهاجم میفهمد این حسابها احتمالاً رمز مشترکی دارند و یک محاسبه را برای چند حساب به کار میبرد.
Salt چگونه جلوی Rainbow Table را میگیرد؟
Salt رشتهای تصادفی است که برای هر رمز عبور جداگانه تولید میشود و همراه آن وارد فرایند هش یا مشتقسازی کلید میشود:
textKDF(password, unique_random_salt)
فرض کنید دو کاربر هر دو رمز Iran1404 را انتخاب کردهاند. اگر سیستم Salt داشته باشد، وضعیت شبیه این خواهد بود:
textکاربر اول: KDF(Iran1404, salt-A) → verifier-A کاربر دوم: KDF(Iran1404, salt-B) → verifier-B
خروجیها متفاوت میشوند، چون Saltها متفاوتاند.
مهاجم دیگر نمیتواند یک جدول عمومی بسازد و آن را روی همه حسابها اجرا کند. برای هر Salt باید محاسبات جداگانه انجام دهد. اگر یک سایت چند میلیون کاربر داشته باشد و برای هر حساب Salt منحصربهفردی به کار ببرد، مزیت اصلی جدولهای ازپیشمحاسبهشده از بین میرود.
OWASP در راهنمای ذخیرهسازی گذرواژهها تأکید میکند که Salt باید تصادفی و منحصربهفرد باشد. Salt معمولاً محرمانه نیست و میتواند کنار verifier ذخیره شود؛ چیزی که باید مخفی بماند، خود گذرواژه و در بعضی معماریها Pepper است.
Salt همه مشکلات را حل نمیکند
Salt مانع Rainbow Table عمومی میشود، اما رمز عبور ضعیف را قوی نمیکند.
اگر مهاجم هش و Salt یک حساب را به دست بیاورد، میتواند برای همان حساب رمزهای احتمالی را یکییکی آزمایش کند:
textحدس رمز → افزودن Salt همان حساب → اجرای KDF → مقایسه با verifier
پس اگر رمز شما 123456، نام تیم فوتبال یا شماره موبایل باشد، مهاجم هنوز شانس بالایی دارد. Salt فقط جلوی استفاده مجدد از یک جدول آماده برای تعداد زیادی حساب را میگیرد.
برای کندکردن این حملات باید از الگوریتمهای مخصوص ذخیرهسازی رمز عبور استفاده شود؛ الگوریتمهایی که عمداً محاسبهشان پرهزینهتر از SHA-256 یا MD5 است.
چرا MD5 و SHA-1 برای ذخیره رمز مناسب نیستند؟
MD5 و SHA-1 برای کاربردهایی مانند بررسی یکپارچگی فایلها یا بعضی کاربردهای قدیمی طراحی شدهاند، نه برای نگهداری رمز عبور.
این الگوریتمها بسیار سریعاند. سرعت بالا برای بررسی فایل مفید است، اما برای رمز عبور به نفع مهاجم تمام میشود. اگر یک کارت گرافیک یا زیرساخت ابری بتواند تعداد زیادی حدس را در هر ثانیه بررسی کند، رمزهای کوتاه و رایج خیلی زود کنار میروند.
حتی SHA-256 هم اگر بهتنهایی و بدون سازوکار کندکننده برای ذخیره گذرواژه استفاده شود، انتخاب مناسبی نیست. NIST در راهنمای هویت دیجیتال خود ذخیرهسازی رازهای حافظهای را با Salt تصادفی و یک تابع مشتقسازی کلید یکطرفه و تکرارشونده توصیه میکند.
الگوریتمهای مناسب برای ذخیرهسازی گذرواژه
Argon2id
Argon2id یکی از انتخابهای پیشنهادی فعلی برای ذخیره گذرواژه است. این الگوریتم علاوه بر زمان، حافظه هم مصرف میکند. همین ویژگی، اجرای حمله گسترده با GPU یا سختافزارهای تخصصی را پرهزینهتر میکند.
OWASP برای یک پیکربندی پایه Argon2id این مقادیر را پیشنهاد کرده است:
textحافظه: 19456 KiB تکرار: 2 موازیسازی: 1
این اعداد نسخه نهایی و همیشگی برای هر سامانه نیستند. تیم فنی باید آنها را با سختافزار سرور، تعداد کاربران و زمان قابلقبول ورود آزمایش کند.
bcrypt
bcrypt سالهاست در سامانههای مختلف استفاده میشود و برای ذخیره گذرواژه گزینهای شناختهشده است. این الگوریتم Salt را در فرایند خود دارد و پارامتر هزینه آن باید متناسب با توان سرور تنظیم شود.
PBKDF2
PBKDF2 نیز با تکرارهای متعدد، هزینه بررسی هر حدس را بالا میبرد. در بعضی سامانهها و استانداردهای سازمانی که پشتیبانی از الگوریتمهای مشخص لازم است، PBKDF2 انتخاب عملی محسوب میشود.
در هر سه حالت، استفاده از کتابخانه معتبر مهم است. پیادهسازی دستی هش، Salt یا پارامترهای رمزنگاری معمولاً ارزش ریسک ندارد.
تفاوت Rainbow Table با Dictionary Attack
این دو حمله شبیه هماند، اما یکسان نیستند.
در Dictionary Attack مهاجم فهرستی از رمزهای محتمل را در زمان حمله آزمایش میکند. این فهرست میتواند شامل کلمات رایج، نامها، شمارهها و رمزهای افشاشده قبلی باشد.
در Rainbow Table بخشی از محاسبات از قبل انجام شده و به شکل فشرده ذخیره شده است. بنابراین مهاجم میکوشد زمان حمله را با هزینه ذخیرهسازی قبلی کاهش دهد.
اگر Salt برای هر حساب یکتا باشد، Rainbow Table عمومی کاربردش را از دست میدهد؛ اما Dictionary Attack اختصاصی همچنان ممکن است.
تفاوت Rainbow Table با Brute Force
در حمله Brute Force، مهاجم همه ترکیبهای ممکن را طبق یک الگو امتحان میکند. برای مثال، ممکن است از همه رمزهای چهاررقمی شروع کند و بعد سراغ رمزهای طولانیتر برود.
Rainbow Table بر مجموعهای از محاسبات پیشین تکیه دارد. این روش برای فضای رمز مشخص، نوع هش مشخص و شرایطی که Salt وجود ندارد یا ثابت است، سود بیشتری دارد.
در عمل، مهاجمان مدرن معمولاً به یک روش محدود نمیمانند. فهرست رمزهای افشاشده، الگوهای رفتاری کاربران، Dictionary Attack، حمله ترکیبی و آزمون آفلاین میتوانند کنار هم استفاده شوند. به همین دلیل دفاع مناسب هم باید چندلایه باشد.
آیا Rainbow Table برای رمزهای فارسی هم کاربرد دارد؟
بله، اما میزان موفقیت به مجموعه رمز و نحوه ذخیرهسازی بستگی دارد.
اگر کاربران از عبارتهای کوتاه فارسی، نام اشخاص، تاریخهای شمسی، شماره موبایل یا ترکیبهای قابل حدس استفاده کنند، مهاجم میتواند این الگوها را در فهرستهای حدس خود قرار دهد. تبدیل صفحهکلید فارسی و انگلیسی هم یک مسئله جداگانه است؛ برای نمونه، بعضی کاربران یک عبارت فارسی را با صفحهکلید انگلیسی تایپ میکنند یا برعکس.
رمزهای مبتنی بر اطلاعات عمومی هم خطرناکاند. نام مدرسه، کد ملی، پلاک خودرو، نام شهر یا تاریخ تولد ممکن است برای صاحب حساب آسان به نظر برسد، اما برای کسی که اطلاعات او را از شبکههای اجتماعی جمع کرده، چندان رازآلود نیست.
زبان رمز تفاوت اساسی ایجاد نمیکند. اگر الگو قابل پیشبینی باشد، فارسی یا انگلیسی بودن آن مشکل را حل نمیکند.
وضعیت کاربران و کسبوکارهای ایرانی
کاربری که از سرویسهای داخلی استفاده میکند، معمولاً نمیتواند نوع الگوریتم ذخیرهسازی رمز را بررسی کند. سایت ممکن است فقط یک فرم ورود ساده داشته باشد و هیچ توضیحی درباره امنیت گذرواژه ارائه ندهد.
چند کار عملی از دست کاربر برمیآید:
- برای هر سایت رمز جداگانه بسازید.
- رمز را حداقل ۱۴ یا ۱۶ نویسه و ترجیحاً بهصورت عبارت چندکلمهای انتخاب کنید.
- از شماره موبایل، تاریخ تولد و نام اعضای خانواده استفاده نکنید.
- احراز هویت دومرحلهای را فعال کنید.
- رمز ایمیل اصلی را با حسابهای دیگر مشترک نگذارید.
- اگر سایتی خبر نشت اطلاعات داد، همان رمز را در هر سرویس دیگری فوراً تغییر دهید.
- از مدیر رمز عبور معتبر استفاده کنید؛ نگهداری دهها رمز متفاوت در ذهن کار سادهای نیست.
برای کسبوکارهای ایرانی، موضوع جدیتر است. پایگاه داده کاربران ممکن است روی سرور داخلی، سرور ابری یا زیرساختی خارج از کشور نگهداری شود. محل سرور، جایگزین طراحی امن نیست. سامانه باید Salt یکتای هر رمز، KDF کند و تکرارشونده، محدودسازی تلاش ورود، ثبت رویدادهای امنیتی و فرایند تغییر رمز امن داشته باشد.
Pepper چه تفاوتی با Salt دارد؟
Pepper یک راز اضافی است که در کنار Salt استفاده میشود، اما برخلاف Salt نباید در همان پایگاه داده قرار بگیرد.
طرح مفهومی میتواند چنین باشد:
textpassword + salt ↓ Argon2id ↓ HMAC با pepper محرمانه ↓ verifier ذخیرهشده
Salt برای هر کاربر متفاوت است و معمولاً همراه verifier ذخیره میشود. Pepper میان کاربران یا یک گروه از آنها مشترک است و باید در سامانهای جدا مانند Secret Vault یا HSM نگهداری شود.
اگر پایگاه داده لو برود اما Pepper در اختیار مهاجم نباشد، یک لایه دفاعی دیگر باقی میماند. بااینحال Pepper جای Salt، الگوریتم مناسب یا رمز قوی را نمیگیرد. اگر Pepper افشا شود، تغییر آن هم ساده نیست؛ چون رمز اصلی کاربران را در اختیار ندارید و ممکن است مجبور شوید فرایند بازنشانی گذرواژه اجرا کنید.
از نگاه کتابهای امنیتی چه میدانیم؟
در کتاب Cryptography Engineering: Design Principles and Practical Applications نوشته نیلز فرگوسن، بروس اشنایر و تادایوشی کوهنو، فصل ۲۱ با عنوان Storing Secrets به نگهداری امن اسرار میپردازد. نگاه این کتاب کاملاً کاربردی است: امنیت واقعی فقط از انتخاب یک الگوریتم مشهور به دست نمیآید؛ نحوه استفاده، مدیریت کلیدها، هزینه حمله و رفتار کاربران هم باید در طراحی دیده شود.
بروس اشنایر در نوشتهها و کتابهای خود بارها روی یک نکته تأکید میکند: سیستم رمزنگاری را نباید با این فرض طراحی کرد که مهاجم فقط از روشهای مورد انتظار ما استفاده میکند. در مورد گذرواژه هم همین مسئله دیده میشود. مدیر سامانه ممکن است تصور کند هشکردن کافی است، اما مهاجم از فهرست رمزهای افشاشده، سختافزار سریع، اطلاعات شبکههای اجتماعی و حملات آفلاین استفاده میکند.
مقاله اوشلین در CRYPTO 2003 نیز نشان میدهد که مهاجم میتواند با جابهجا کردن هزینه میان حافظه و زمان، روشهای محاسباتی را بهینه کند. به زبان ساده، امنیت نباید فقط با این پرسش سنجیده شود که «آیا هش قابل معکوس کردن است؟» پرسش دقیقتر این است: «هزینه آزمایش هر حدس برای مهاجم چقدر است؟»
یک طرح امن برای ذخیره رمز عبور
برای یک سامانه معمولی، جریان امن میتواند چنین باشد:
textرمز عبور کاربر + Salt تصادفی و یکتا ↓ Argon2id یا الگوریتم مناسب دیگر ↓ ذخیره verifier، Salt و پارامترهای لازم
Salt نباید برای همه کاربران یک مقدار ثابت داشته باشد. همچنین نباید از مقدارهایی مثل نام سایت، تاریخ امروز یا شناسه کاربر بهعنوان Salt استفاده شود؛ Salt باید تصادفی و غیرقابل پیشبینی باشد.
در زمان ورود، سامانه رمز واردشده را با همان Salt و همان پارامترها پردازش میکند و خروجی را با verifier ذخیرهشده مقایسه میکند. رمز اصلی نباید در پایگاه داده ذخیره شود و نباید در گزارشهای خطا، فایلهای پشتیبان یا سامانههای ثبت رویداد باقی بماند.
اگر پایگاه داده لو رفت چه میشود؟
اگر رمزها بهصورت متن ساده ذخیره شده باشند، نشت پایگاه داده تقریباً به معنای افشای مستقیم حسابهاست.
اگر رمزها با MD5 یا SHA-1 سریع و بدون Salt ذخیره شده باشند، Rainbow Table و فهرستهای هششده میتوانند تعداد زیادی از آنها را سریع پیدا کنند.
اگر رمزها با Salt یکتا و Argon2id، bcrypt یا PBKDF2 مناسب ذخیره شده باشند، مهاجم باید برای هر حساب، حدسها را جداگانه و با هزینه بیشتری بررسی کند. این وضعیت خطر را از بین نمیبرد، اما زمان، هزینه و احتمال موفقیت حمله را بالا میبرد.
در چنین حادثهای، تغییر رمزهای تکراری، باطلکردن نشستهای فعال، اجباریکردن بازنشانی رمز و اطلاعرسانی شفاف اهمیت دارد. پنهانکردن نشت اطلاعات فقط زمان بیشتری به مهاجم میدهد.
برداشت نهایی
Rainbow Table رمزنگاری را نمیشکند و هش را بهصورت جادویی «رمزگشایی» نمیکند. این روش از رمزهای قابل پیشبینی، هشهای سریع و نبود Salt استفاده میکند تا محاسبات قبلی را دوباره به کار ببرد.
یک Salt تصادفی و یکتا، جدول عمومی را برای هر حساب بیفایده میکند. یک KDF کند و حافظهمحور، حدسزدن آفلاین را پرهزینهتر میسازد. رمز طولانی و غیرقابل پیشبینی نیز نقطه شروع حمله را از دسترس دور میکند.
برای کاربر ایرانی، سادهترین نسخه این توصیهها روشن است: یک رمز طولانی و اختصاصی برای ایمیل اصلی، استفاده از مدیر رمز عبور، فعالکردن ورود دومرحلهای و کنار گذاشتن رمزهایی که از شماره موبایل یا تاریخ تولد ساخته شدهاند. همین چند تغییر، فاصله میان یک حساب معمولی و هدفی آسان را بسیار بیشتر میکند.
منابع
| منبع | نویسنده یا سازمان | نوع منبع | کاربرد در مقاله |
|---|---|---|---|
| Making a Faster Cryptanalytic Time-Memory Trade-Off | Philippe Oechslin | مقاله علمی، CRYPTO 2003، LNCS 2729، صفحات 617–630 | معرفی Rainbow Table و مبادله زمان و حافظه |
| Cryptography Engineering: Design Principles and Practical Applications | Niels Ferguson، Bruce Schneier، Tadayoshi Kohno | کتاب، Wiley، 2010 | فصل ۲۱، Storing Secrets؛ نگهداری امن اسرار و گذرواژهها |
| Password Storage Cheat Sheet | OWASP | راهنمای فنی | Salt، Pepper، Argon2id، bcrypt و PBKDF2 |
| NIST SP 800-63B-4 | National Institute of Standards and Technology | استاندارد و راهنمای رسمی | ذخیرهسازی Saltشده و تکرارشونده رازهای حافظهای |
| Strength of Passwords | NIST | بخش تخصصی راهنمای هویت دیجیتال | حملات آفلاین، گذرواژههای ضعیف و هزینه محاسباتی حدسها |
| Adding Salt to Hashing: A Better Way to Store Passwords | Auth0 | مقاله آموزشی فنی | توضیح ساده تفاوت هش معمولی، Salt و Rainbow Table |
نظر شما در مورد این محتوا چیست؟


