في جملة واحدة
خوارزميات تجزئة كلمات المرور مثل bcrypt و Argon2 تحوّل كلمة مرور المستخدم إلى سلسلة طويلة من الحروف غير القابلة للعكس، ومصممة خصيصًا لتكون بطيئة ومكلفة حسابيًا، مما يجعل من الصعب جدًا على المهاجمين كسرها حتى لو سرقوا قاعدة بيانات المستخدمين بالكامل.
المشكلة التي يحلها
في العصور الرقمية المظلمة، كان المطورون يخزنون كلمات مرور المستخدمين كنص عادي (plaintext). إذا اخترق هاكر قاعدة البيانات، فسيحصل على ملف يحتوي على كل اسم مستخدم وكلمة المرور الخاصة به. انتهت اللعبة. ولك أن تتخيل حجم الكارثة.
الخطوة الأولى للأمام كانت "التجزئة" (hashing). بدلاً من تخزين P@ssword123، كنت تخزن الهاش الخاص بها - وهي سلسلة ذات طول ثابت يتم إنشاؤها بواسطة خوارزمية مثل MD5 أو SHA-1. عندما يقوم المستخدم بتسجيل الدخول، تقوم بعمل هاش لكلمة المرور التي أدخلها وترى ما إذا كانت تتطابق مع الهاش المخزن. كان هذا أفضل، لكن كان به عيب قاتل: جداول قوس قزح (rainbow tables). بما أن دالة الهاش تنتج دائمًا نفس المخرجات لنفس المدخلات (على سبيل المثال، password دائمًا ما يتم تجزئتها إلى 5f4dcc3b5aa765d61d8327deb882cf99 باستخدام MD5)، قام المهاجمون بحساب الهاش مسبقًا لمليارات كلمات المرور الشائعة وتخزينها في جدول بحث عملاق. يمكن عكس الهاش المسروق إلى كلمة المرور الأصلية في أجزاء من الثانية.
التطور التالي كان "التمليح" (salting). قبل تجزئة كلمة المرور، تضيف سلسلة عشوائية فريدة تسمى "الملح" (salt) إليها. لذا بدلاً من تجزئة P@ssword123، ستقوم بتجزئة P@ssword123 + aBcDeFg12345. يتم بعد ذلك تخزين الملح بجانب الهاش في قاعدة البيانات. هذا يبطل مفعول جداول قوس قزح تمامًا، لأن هاش كل مستخدم الآن فريد من نوعه، حتى لو اختاروا جميعًا كلمة المرور "password". سيتعين على المهاجم إنشاء جدول قوس قزح جديد لكل ملح فريد لكل مستخدم، وهو أمر غير ممكن حسابيًا.
لكن ظهر شرير جديد على الساحة: القوة الحاسوبية الخالصة. يمكن لوحدات معالجة الرسومات (GPUs) والأجهزة المخصصة (ASICs) الحديثة تجربة مليارات من تركيبات كلمات المرور المملحة في الثانية ضد هاش واحد مسروق. خوارزميات التجزئة مثل SHA-256 سريعة حسب التصميم، وهو أمر رائع للتحقق من سلامة الملفات ولكنه فظيع لحماية كلمات المرور.
هذه هي المشكلة التي وُلدت bcrypt و Argon2 لحلها. إنها دوال تجزئة كلمات المرور (Password Hashing Functions - PHFs)، وهي فئة خاصة من خوارزميات الهاش التي تكون بطيئة ومستهلكة للموارد بشكل متعمد ومؤلم. إنها تجعل التحقق من كلمة مرور واحدة مكلفًا لدرجة أن القوة الغاشمة (brute-forcing) على قاعدة بيانات مسروقة تصبح كابوسًا اقتصاديًا وزمنيًا للمهاجم.
كيف يعمل تحت الغطاء
السحر وراء تجزئة كلمات المرور الحديثة لا يقتصر فقط على الخوارزمية؛ بل يتعلق بجعل تلك الخوارزمية تقوم بكمية قابلة للتكوين من "العمل". هذا ما يسمى غالبًا "تمديد المفتاح" (key stretching).
الفكرة الأساسية: التكلفة التكيفية
كل من bcrypt و Argon2 لديهما عوامل "تكلفة" أو "عمل" قابلة للضبط. هذه هي قوتهما الخارقة. إنه رقم تقوم بتعيينه يحدد مدى بطء واستهلاك عملية التجزئة للموارد. الفكرة هي ضبط هذه التكلفة بحيث يستغرق تجزئة كلمة المرور على الخادم الخاص بك وقتًا معقولاً (على سبيل المثال، 100-500 مللي ثانية) - بطيء بما يكفي لإحباط المهاجم، ولكنه سريع بما يكفي لعدم إزعاج المستخدمين.
مع زيادة سرعة أجهزة الكمبيوتر وفقًا لقانون مور (Moore's Law)، يمكنك ببساطة زيادة عامل التكلفة كل بضع سنوات للحفاظ على نفس المستوى من الأمان. "تمرين" التجزئة الخاص بك يزداد صعوبة كلما أصبحت أجهزة المهاجم أقوى.
Bcrypt: المخضرم الموثوق
Bcrypt، التي تم تقديمها في عام 1999، تعتمد على شيفرة التشفير Blowfish. دفاعها الأساسي ضد هجمات القوة الغاشمة هو أنها ليست فقط مكثفة حسابيًا، ولكنها أيضًا تستهلك الكثير من الذاكرة (memory intensive).
تقوم الخوارزمية بمعالجة كلمة المرور والملح بشكل متكرر، ولكن جزءًا أساسيًا من حالتها الداخلية يتم تخزينه بطريقة تتطلب وصولاً متكررًا إلى جزء من ذاكرة الوصول العشوائي (RAM). في حين أن وحدات المعالجة المركزية (CPUs) جيدة في هذا، فإن وحدات معالجة الرسومات (GPUs) - سلاح المهاجم المفضل - تزدهر على العمليات الحسابية البسيطة والمتوازية مع الحد الأدنى من الوصول إلى الذاكرة. من خلال إجبار العملية على الغوص باستمرار في الذاكرة، تعرقل bcrypt عمل أجهزة كسر التشفير المعتمدة على الـ GPU.
تبدو سلسلة هاش bcrypt النموذجية هكذا:
$2b$12$J9yLsf9dTOZiCEpT1zO97uF2Yp3uG/yG4Q6V.C1rCg8u6d5qO5GqS
دعنا نفككها:
| الجزء | مثال | المعنى |
|---|---|---|
| الخوارزمية | $2b |
تحدد خوارزمية bcrypt وإصدارها. |
| عامل التكلفة | 12 |
عامل العمل. عدد التكرارات هو 212. زيادة هذا الرقم بمقدار 1 يضاعف الوقت. |
| الملح والهاش | J9yLsf...d5qO5GqS |
أول 22 حرفًا هي الملح المشفر بـ Base64. الباقي هو خلاصة كلمة المرور المجزأة الفعلية. |
بشكل حاسم، كل المعلومات اللازمة للتحقق من كلمة المرور — الخوارزمية، والتكلفة، والملح — يتم تخزينها هناك في سلسلة واحدة ملائمة.
Argon2: البطل الحديث
كانت Argon2 هي الفائزة في مسابقة تجزئة كلمات المرور (Password Hashing Competition - PHC) في عام 2015، وهو جهد استمر لعدة سنوات لإيجاد خوارزمية تجزئة كلمات مرور جديدة وموحدة. تم تصميمها لتكون أكثر مقاومة لهجمات الأجهزة الحديثة من bcrypt.
توفر ثلاثة أذرع تحكم مختلفة لضبط تكلفتها:
- تكلفة الذاكرة (m): كمية الذاكرة (بالكيلوبايت KiB) التي ستستخدمها الخوارزمية. هذا هو دفاعها الرئيسي ضد تسريع الأجهزة، حيث يمكن ضبطها لتتطلب ذاكرة أكبر من المتاحة على نواة GPU واحدة.
- تكلفة الوقت (t): عدد التكرارات، أو المرورات، التي تقوم بها الخوارزمية على الذاكرة. هذا يزيد من إجمالي وقت الحساب.
- التوازي (p): عدد الخيوط (threads) أو "المسارات" التي يمكن استخدامها. يسمح هذا للخوارزمية بالاستفادة من وحدات المعالجة المركزية متعددة النواة للتجزئة، ولكنه يعني أيضًا أن المهاجم يمكنه استخدام نفس التوازي. إنه مقياس للمفاضلة.
البديل الموصى به هو Argon2id، وهو مزيج هجين من نسختين أخريين. يوفر مقاومة متوازنة ضد كل من الهجمات الجانبية (side-channel attacks) (حيث يحلل المهاجم تأثيرات النظام مثل استهلاك الطاقة) وهجمات الكسر باستخدام GPU.
سلسلة هاش Argon2id متشابهة في كونها مكتفية ذاتيًا:
$argon2id$v=19$m=65536,t=3,p=4$c29tZXNhbHQ$RdescudvJCsgt3ub+b+dWRWJTIT0T7cKLfgflAIk124
| الجزء | مثال | المعنى |
|---|---|---|
| الخوارزمية | $argon2id |
تحدد خوارزمية Argon2id. |
| الإصدار | v=19 |
رقم إصدار الخوارزمية. |
| المعلمات | m=65536,t=3,p=4 |
تكاليف الذاكرة والوقت والتوازي. |
| الملح (Salt) | c29tZXNhbHQ |
الملح العشوائي المشفر بـ Base64. (هذا يفك تشفيره إلى "somesalt"). |
| الهاش (Hash) | Rdescudv...flAIk124 |
خلاصة كلمة المرور المجزأة المشفرة بـ Base64. |
عملية التحقق
هذا هو الجزء الجميل. أنت أبدًا لا تفك تشفير الهاش. التحقق هو شارع باتجاه واحد.
- يحاول مستخدم تسجيل الدخول باستخدام
P@ssword123. - يسترجع تطبيقك سلسلة الهاش الكاملة الخاصة به من قاعدة البيانات (على سبيل المثال، سلسلة Argon2id من الجدول أعلاه).
- يقوم الكود الخاص بك بتحليل تلك السلسلة، واستخراج الخوارزمية (
argon2id)، والإصدار (19)، وعوامل التكلفة (m=65536, t=3, p=4)، والملح (c29tZXNhbHQ). - ثم يأخذ كلمة المرور التي أدخلها المستخدم للتو (
P@ssword123) ويقوم بتجزئتها باستخدام نفس هذه المعلمات بالضبط. - أخيرًا، يقارن الهاش الذي تم إنشاؤه حديثًا مع جزء الهاش من السلسلة الموجودة في قاعدة البيانات. إذا كانا متطابقين، تكون كلمة المرور صحيحة. وإلا، يتم رفض الوصول.
قصص من الواقع
اختراق LinkedIn عام 2012: درس في السرعة
في عام 2012، تعرضت LinkedIn لاختراق هائل، وتم تسريب أكثر من 6.5 مليون هاش لكلمات مرور المستخدمين إلى منتدى هاكرز روسي. المشكلة؟ كانت الهاشات من نوع SHA-1 غير مملحة (unsalted). في غضون ساعات، بدأ عشاق الأمن والقراصنة على حد سواء سباقًا لكسرها. نمت قوائم كلمات المرور التي تم كسرها بنجاح دقيقة بدقيقة. نظرًا لأن الهاشات كانت "سريعة" وغير مملحة، كان كل ما يتطلبه الأمر هو جدول قوس قزح واحد ضخم. كان الضرر الذي لحق بسمعة الشركة هائلاً.
الدرس: هاش سريع وغير مملح بالكاد أفضل من النص العادي. كان اختراق LinkedIn بمثابة جرس إنذار كبير للصناعة دفع عددًا لا يحصى من الشركات إلى اعتماد التجزئة البطيئة والمملحة مثل bcrypt أخيرًا.
موقع التجارة الإلكترونية الذي كسب الوقت
أصر مطور ذكي في شركة ناشئة، "CircuitCraze"، على استخدام Argon2id لقاعدة بيانات العملاء الجديدة، وقام بضبط المعلمات لتستغرق حوالي 300 مللي ثانية لكل عملية تسجيل دخول. بعد عام، كشفت حاوية تخزين سحابية ذات إعدادات خاطئة عن نسخة احتياطية من قاعدة البيانات. تم تنزيل جدول users، بكل ما فيه من هاشات Argon2id، بواسطة مهاجم. قام الفريق على الفور بفرض إعادة تعيين كلمة المرور عالميًا. المهاجم، الذي واجه احتمال إنفاق آلاف الدولارات على الحوسبة السحابية لمجرد كسر حفنة من كلمات المرور من مجموعة بيانات أصبحت الآن عديمة الفائدة، استسلم ببساطة وانتقل إلى أهداف أسهل.
الدرس: التجزئة القوية لكلمات المرور هي دفاعك الأساسي بعد الاختراق. إنها لا تمنع الاختراق، لكنها تحول تسرب البيانات الكارثي إلى حادث يمكن التحكم فيه عن طريق منحك وقتًا ثمينًا للتصرف.
زحف عامل التكلفة
أطلق فريق تطبيق ويب جديدًا في عام 2015، واختار بحكمة bcrypt بعامل تكلفة 10. كان يعمل بشكل رائع. تقدم سريعًا إلى اليوم. فعل قانون مور فعله، وأصبح عامل التكلفة 10 الآن يعتبر ضعيفًا. أشار تدقيق أمني إليه على أنه خطر ذو أولوية عالية. يواجه الفريق الآن معضلة: كيف يقومون بترقية الأمان لملايين المستخدمين دون إجبارهم على إعادة تعيين كلمة المرور بشكل جماعي؟ الحل الأنيق: في المرة التالية التي يقوم فيها المستخدم بتسجيل الدخول، يتحقق النظام من كلمة المرور الخاصة به مقابل الهاش القديم بعامل تكلفة 10. إذا كانت صحيحة، فإنه يعيد على الفور تجزئة نفس كلمة المرور بعامل تكلفة جديد قدره 13 ويستبدل الهاش القديم في قاعدة البيانات.
الدرس: أمان كلمات المرور ليس شيئًا "تضبطه وتنساه". عوامل التكلفة هي إعداد حي يجب مراجعته وزيادته بشكل دوري لمواكبة قدرات المهاجمين.
أخطاء وشراك شائعة
- استخدام هاش سريع. لا تفعل ذلك. MD5, SHA-1, SHA-256, SHA-512... هذه الخوارزميات مخصصة للمجموع الاختباري (checksums)، وليس لكلمات المرور. تم تصميمها لتكون سريعة، وهو بالضبط ما لا تريده.
- اختراع خوارزمية التشفير الخاصة بك. لا تحاول أبدًا اختراع مخطط تجزئة خاص بك، مثل
sha512(password + salt). استخدم مكتبة قياسية، ومراجعة من قبل النظراء، ومجربة في المعارك لـ bcrypt أو Argon2 تقوم بذلك بشكل صحيح. - استخدام salt ثابت أو مُعاد استخدامه. يجب أن يكون الملح عشوائيًا من الناحية التشفيرية وفريدًا لكل كلمة مرور تخزنها. تخزين ملح فريد بجانب كل هاش هو الممارسة الصحيحة والمعيارية.
- ضبط التكلفة على مستوى منخفض جدًا. عامل تكلفة bcrypt أقل من 12 (في عام 2024) أو معلمات Argon2 ضعيفة يبطل الغرض بأكمله. أنت فقط تمنح المهاجم يومًا سهلاً. اضبطه ليكون بطيئًا قدر ما يمكنك تحمله.
- ضبط التكلفة على مستوى عالٍ جدًا. إذا استغرقت عملية التجزئة 10 ثوانٍ، فسوف تنتهي مهلة نموذج تسجيل الدخول الخاص بك وسيبدو معطلاً. والأسوأ من ذلك، أنك تفتح الخادم الخاص بك لهجوم حجب الخدمة (Denial-of-Service - DoS) حيث يمكن لشخص ما أن يطحن وحدات المعالجة المركزية الخاصة بك حتى التوقف بمجرد إرسال طلبات متكررة إلى نموذج تسجيل الدخول.
- تخزين خلاصة الهاش فقط. تحتوي السلاسل التي تم إنشاؤها بواسطة bcrypt و Argon2 على الخوارزمية والتكاليف والملح لسبب ما. يجب عليك تخزين تلك السلسلة بأكملها (على سبيل المثال، في عمود
VARCHAR(255)) لتكون قادرًا على التحقق من كلمات المرور في المستقبل.
لماذا يجب أن يكون على رادارك
إذا كان عملك يتضمن بناء أي شيء يحتوي على نموذج تسجيل دخول، فأنت بحاجة إلى فهم هذا.
- مطور الواجهة الخلفية (Backend) والمطور الشامل (Full-Stack): هذه مسؤوليتك المباشرة. إذا أخطأت في هذا، فإنك تعرض كل مستخدميك للخطر.
- مهندسو الأمن و DevOps: أنتم من يضع السياسات، ويجري عمليات التدقيق، ويدير البنية التحتية. تحتاجون إلى معرفة كيف يبدو "الجيد" وكيفية اختباره.
- مطور الواجهة الأمامية (Frontend): فهم أن تسجيل الدخول الآمن قد يستغرق بضع مئات من الميلي ثانية يفسر سبب حاجتك إلى تقديم ملاحظات للمستخدم (مثل رمز تحميل دوار) لمنعهم من النقر بغضب على زر "تسجيل الدخول".
باختصار، إذا ظهرت الكلمات "مستخدم" أو "حساب" أو "كلمة مرور" في أي مكان في متطلبات مشروعك، فإن تجزئة كلمات المرور هي مفهوم أساسي لا يمكنك تجاهله.
تعمق أكثر
- OWASP Password Storage Cheat Sheet — الدليل الأساسي والموثوق للمطورين.
- Argon2 Specification — الورقة الرسمية التي تصف كيفية عمل Argon2.
- How To Safely Store A Password by Coda Hale — تدوينة كلاسيكية من عام 2010 تشرح "لماذا" bcrypt لجيل من المطورين.
- Bcrypt on Wikipedia — نظرة عامة قوية على تاريخ الخوارزمية وتصميمها.
- Argon2 on Wikipedia — خلفية عن مسابقة تجزئة كلمات المرور وتصميم Argon2.
- Password Hashing Competition — الموقع الرسمي للمسابقة التي توجت Argon2.