ما هو التمليح في مجال الأمن؟ شرح تجزئة كلمات المرور
في يونيو 2012، قام مهاجم بنشر 117 مليون سجل حساب على موقع لينكدإن في منتدى روسي. كانت القائمة عبارة عن سلسلة من تجزئات SHA-1 غير المُملّحة. تتميز خوارزمية SHA-1 بسرعتها، ولكن بدون استخدام الملح لفصل كلمات المرور المتطابقة، تكررت نفس التجزئة آلاف المرات. في غضون 72 ساعة تقريبًا، تمكن باحثو الأمن من فك تشفير حوالي 90% من الملف. وعندما عاودت هذه الثغرة الظهور في مايو 2016 ضمن مجموعة بيانات تضم 167 مليون سجل، استُخدمت هذه البيانات في حملات اختراق البيانات لسنوات.
كان من الممكن أن يُخفف هذا الاختراق من وطأته - وهو إضافة قيمة عشوائية (Salt) إلى كل كلمة مرور مُخزّنة - أن يكون موجودًا بالفعل في عام 1979. يُطلق عليه اسم "التمليح" (Salting). إنه ليس جديدًا، ولا مُكلفًا، ولا يُعتبر ذكيًا بشكل خاص. إنه الفرق بين أن يكون تسريب قاعدة البيانات حادثًا محصورًا وبين أن يُصبح مشكلة كلمات مرور للجميع لمدة نصف عقد.
لا تزال معظم حالات فشل تخزين كلمات المرور الحديثة تنبع من السبب الجذري نفسه: شخص ما قرر أن استخدام خوارزمية SHA-256 كافٍ. تشرح هذه المقالة ماهية التمليح، وكيفية عمله عمليًا، وما يحمي منه وما لا يحمي منه، وما توصي به OWASP كخيار افتراضي لعام 2026.
ما هو التمليح في مجال الأمن وتجزئة كلمات المرور؟
باختصار، تعني عملية التمليح إضافة بيانات عشوائية إلى كلمة المرور قبل تشفيرها. تُولّد هذه القيمة العشوائية - الملح - مرة واحدة لكل حساب عند إنشائها مع تجزئة كلمة المرور الجديدة، وتُخزّن بشكل واضح بجانب التجزئة الناتجة، ثم تُقرأ عند كل تسجيل دخول. الملح ليس مفتاحًا، ولا سرًا، ولا تشفيرًا. إنه مُعدِّل عام وظيفته الوحيدة هي ضمان عدم مشاركة كلمة المرور المُشفّرة نفسها بين مستخدمين يمتلكان نفس كلمة المرور.
التشفير وحده عملية أحادية الاتجاه. عند إدخال كلمة مرور عبر خوارزمية SHA-256 أو Argon2id، نحصل على قيمة ثابتة الطول لا يمكن لأي خوارزمية عكسها. لكن المشكلة تكمن في أن عبارة "لا توجد خوارزمية" تستثني طريقة مختصرة سهلة، وهي البحث عن قيمة التشفير في قاموس مُعدّ مسبقًا. يُغلق التمليح هذه الطريقة المختصرة. فإضافة قيمة ملح إلى عملية التشفير تُنتج قيمة تشفير فريدة لكل مستخدم، حتى لو كانت كلمات المرور الأصلية متطابقة تمامًا. لن تتكرر كلمات المرور الشائعة مثل "password" و"qwerty" في قاعدة البيانات. يضمن التمليح أن تسريب صف واحد لا يُفصح للمهاجم عن أي معلومات تخص أي مستخدم آخر.
ثلاثة قواعد تميز الملح القابل للاستخدام عن الملح غير القابل للاستخدام. القاعدة الأولى: لكل كلمة مرور ملحها العشوائي الخاص بها، والذي يتم إنشاؤه حديثًا عند تسجيل المستخدم أو إعادة تعيينه. كلمة المرور المُملحة المُعاد استخدامها عبر حسابات متعددة لا تُعدّ أفضل حالًا من كلمة المرور غير المُملحة - فالهجوم الجماعي يعمل بنفس الطريقة. القاعدة الثانية: قد يكون الملح مُتاحًا للعامة. معرفة الملح بحد ذاتها لا تُتيح للمهاجم أي اختصار للوصول إلى دالة التجزئة الأساسية. لذلك، يُخزّن الملح في قاعدة البيانات بجوار دالة التجزئة، وهذا الموقع مقبول، بل ومُستحسن. القاعدة الثالثة: تُستخرج قيم الملح من مُولّد أرقام شبه عشوائية آمن تشفيريًا. يُتيح نظام لينكس الوصول إلى أحد هذه المُولّدات من خلال `getrandom(2)`. ويُطلق عليه Node اسم `crypto.randomBytes`. وتُغلّفه مكتبة بايثون القياسية في `secrets.token_bytes`. أما `Math.random()` غير المُشفّر فهو غير مناسب، على الرغم من ظهوره في التعليمات البرمجية المُدققة بشكل أكبر بكثير مما ينبغي.
يجب أن يحصل شخصان يختاران كلمة المرور "hunter2" على قيمتين مختلفتين تمامًا لتجزئة البيانات المخزنة. ويتحقق ذلك من خلال إضافة قيمة عشوائية (Salt). في حال عدم إضافة هذه القيمة، لن يقتصر تسريب قاعدة البيانات على قيم التجزئة فحسب، بل سيشمل أيضًا شبكة العلاقات الاجتماعية التي تربط المستخدمين بكلمات المرور المختلفة.
كيف تعمل عملية إضافة الملح إلى كلمة المرور
تنقسم الآلية إلى أربع خطوات، وتظهر عشر سنوات من اختراقات تخزين كلمات المرور أن كل فشل تقريبًا يحدث لأن شخصًا ما تخطى إحدى هذه الخطوات.
تُنفَّذ الخطوة الأولى عند التسجيل. يطلب التطبيق من مولد الأرقام العشوائية المشفرة (CSPRNG) ما بين 16 و32 بايتًا عشوائيًا. هذا هو ما يُعرف بالملح (Salt). تُشير إرشادات OWASP لعام 2025 إلى أن 16 بايتًا (128 بتًا) هي الحد الأدنى؛ بينما يُوصي كلٌّ من auth0 والعديد من مُوردي برامج إدارة كلمات المرور بالوصول إلى 32 بايتًا. يُحدد معيار NIST SP 800-63B-4 الحد الأدنى بأربعة بايتات، ولكنه يُحذِّر من أن حالات التصادم المرتبطة بتواريخ ميلاد المستخدمين تبدأ بالظهور عند حوالي 65 ألف مستخدم بهذا الحجم، ولهذا السبب لا يستخدم أحد فعليًا 4 بايتات.
في الخطوة الثانية، يتم دمج الملح مع كلمة المرور التي اختارها المستخدم. يُعدّ الربط التسلسلي الشكل الأكثر شيوعًا، حيث يُوضع الملح قبل أو بعد سلسلة كلمة المرور. تستخدم بعض الأنظمة خوارزمية HMAC بدلاً من ذلك، حيث تُعامل الملح كمفتاح HMAC، مما يُجنّب بعض مشكلات امتداد الطول غير الشائعة في الربط التسلسلي المباشر.
في الخطوة الثالثة، يتم تمرير المدخلات المجمعة عبر خوارزمية تجزئة كلمات المرور - ما يُعرف في كتب التشفير بدالة اشتقاق المفتاح (KDF). في هذه الخطوة، كانت معظم الفرق تفشل، غالبًا باللجوء إلى خوارزمية تجزئة عامة والاعتقاد بأن المهمة قد أُنجزت. خوارزمية SHA-256 وحدها غير مناسبة لتخزين كلمات المرور. في عام 2026، كانت وحدة معالجة الرسومات (GPU) المخصصة للمستهلكين تُجري أكثر من مئة مليار عملية تجزئة SHA-256 في الثانية، لذا حتى مع استخدام الملح (Salt)، تبقى تكلفة التخمين في التجزئة التشفيرية ضئيلة. يُقضي استخدام الملح على هجمات جداول قوس قزح، ولكنه لا يُبطئ عملية كسر كلمات المرور بالقوة الغاشمة. الأداة المناسبة هنا هي دالة بطيئة عمدًا وتستهلك ذاكرة كبيرة: Argon2id هي الخوارزمية الافتراضية المفضلة لدى OWASP، مع قبول scrypt وbcrypt، وPBKDF2 مع السماح بعدد تكرارات عالٍ جدًا حيثما يُلزم معيار FIPS-140 بهذا الاختيار.
الخطوة الرابعة تخزن كلاً من قيمة التجزئة والملح. تتولى المكتبات الحديثة تنسيق التخزين، لذا لن تحتاج إلى إدارة الملح المخزن يدويًا. يبدو ناتج bcrypt كالتالي: `$2b$12$9f4c8a7b...kQR8YZpL9` - يحمل هذا النص المفرد مُعرّف الخوارزمية، وعامل التكلفة، والملح، وقيمة التجزئة. يستخدم Argon2id تنسيق سلسلة PHC المماثل، `$argon2id$v=19$m=19456,t=2,p=1$$`. ما عليك سوى كتابة هذا النص في عمود قاعدة البيانات وتركه. لقد قامت المكتبة بكل ما يلزم لتخزين كلمات المرور بشكل آمن - توليد بيانات عشوائية للملح، وتشغيل كلمة المرور من خلال خوارزمية تجزئة بطيئة، وتجميع النتيجة لاسترجاعها.
تتبع عملية تسجيل الدخول نفس المسار ولكن بشكل عكسي. يبحث التطبيق عن قيمة التشفير (salt) الخاصة بالمستخدم والتجزئة المخزنة، ثم يُمرر كلمة المرور المُدخلة عبر نفس الخوارزمية باستخدام نفس قيمة التشفير، ويقارن النتيجة بالتجزئة المخزنة باستخدام مقارنة ثابتة الوقت. يُعدّ ثبات الوقت أمرًا بالغ الأهمية: فاستخدام عامل المقارنة `==` بشكل بسيط يُسرّب معلومات حول عدد البايتات المتطابقة، مما يُؤدي إلى ثغرات أمنية حقيقية تسمح بهجمات التوقيت. لذا، يُنصح باستخدام `hmac.compare_digest` أو `crypto.timingSafeEqual` أو ما يُعادلها في إطار العمل الخاص بك.

لماذا يُعدّ التمليح مهمًا: مشكلة طاولة قوس قزح
تُعدّ جداول قوس قزح الهجوم الذي صُممت تقنية التمليح خصيصًا للتصدي له. تخيّل جدول بحث مُعدّ مسبقًا يربط كل كلمة مرور محتملة - كل كلمة في القاموس، وكل صيغة شائعة، وكل إدخال في قائمة مُسرّبة - بقيمتها المُجزأة SHA-256. هذه الجداول موجودة، ويتم بيعها في منتديات اختراق الأنظمة، وتصل أحجامها إلى تيرابايتات. بمجرد أن يحصل المهاجم على نسخة من قاعدة بيانات تحتوي على قيم التجزئة غير المُملّحة، يصبح البحث عن قيمة تجزئة في جدول قوس قزح مجرد استعلام في قاعدة البيانات، وليس عملية اختراق. حدث هذا بالضبط مع لينكدإن عام 2012: 117 مليون قيمة تجزئة SHA-1 غير مُملّحة مقابل جدول قوس قزح، وتم اختراق 90% منها في غضون ثلاثة أيام تقريبًا.
بإضافة قيمة ملح لكل مستخدم، تتوقف جداول قوس قزح عن العمل. سيحتاج المهاجم إلى جدول مُعدّ مسبقًا لكل قيمة ملح فريدة. مع قيمة ملح عشوائية بحجم 16 بايت، يعني ذلك 117 مليون جدول مختلف لـ 117 مليون مستخدم، وسيظل حجم كل جدول تيرابايت. تكاليف التخزين وحدها تجعل هذا الأمر غير عملي. وبالتالي، يختفي هذا الهجوم من نموذج التهديد.
هذه هي وظيفة الملح (Salt) بالكامل. وهي محدودة النطاق عمدًا. لا يُبطئ الملح محاولة اختراق مُتعمدة ضد مستخدم مُحدد. ولا يمنع الملح حشو بيانات الاعتماد من تسريب سابق. ولا يُجدي الملح نفعًا إذا كانت كلمة المرور نفسها "123456" - سيُجرب المُهاجم القاموس الواضح، ويُعاد حساب الملح لكل تخمين، لكن ذلك لا يُغير تكلفة التخمين بشكل ملحوظ.
ما يُخففه التمليح بشكل موثوق: جداول قوس قزح، وتسريب معلومات إعادة استخدام كلمات المرور بين المستخدمين في قاعدة البيانات نفسها. ما يُخففه التجزئة البطيئة: تكلفة كل محاولة تخمين. ما يُخففه بيبر: سرقة قاعدة البيانات فقط. ما تُخففه المصادقة متعددة العوامل: حشو بيانات الاعتماد. التمليح هو طبقة أمان واحدة ضمن مجموعة طبقات الأمان - إضافة ملح لزيادة صعوبة كسر كلمات المرور لا يعني جعل كل كلمة مرور على حدة صعبة التخمين. الهدف من التمليح هو الحصول على تجزئة مختلفة لكل مستخدم؛ أما جعل كل محاولة تخمين مكلفة فهو مشكلة منفصلة.
التجزئة مقابل التشفير مقابل إضافة الملح
ثلاثة مصطلحات يختلط الأمر على البعض، خاصة في كتابات غير المتخصصين. وهي ليست قابلة للتبادل.
| التشفير | التجزئة | التمليح | |
|---|---|---|---|
| قابل للعكس | نعم، بالمفتاح | لا، هذا مقصود. | مُعدِّل، وليس قائمًا بذاته |
| طول الإخراج | متغير، يطابق المدخلات | ثابت (عادةً 256 بت) | غير متوفر — يُغير مُدخل التجزئة |
| يستخدم لـ | سرية البيانات | سلامة البيانات، وتخزين كلمات المرور | تقوية الهاش |
| المفتاح مطلوب | نعم، سر | لا | لا، يستخدم ملحًا عشوائيًا |
يحمي التشفير البيانات التي ترغب في استرجاعها لاحقًا. يحتفظ المُستقبِل بالمفتاح، ويُطبّقه، ثم يقرأ النص الأصلي. التجزئة عملية أحادية الاتجاه: بمجرد تحويل كلمة المرور إلى تجزئة، لا يمكن لأي خوارزمية عكسها. أما التمليح فهو مُعدِّل يُطبَّق على مُدخلات دالة التجزئة، وليس له معنى في حد ذاته.
يُعدّ اختراق بيانات أدوبي عام 2013 مثالًا تحذيريًا في هذا السياق. فقد خزّنت أدوبي 153 مليون سجل مستخدم عن طريق تشفير كلمات المرور باستخدام خوارزمية 3DES في وضع ECB تحت مفتاح واحد مُعمّم على مستوى الموقع. كان هذا الخيار فاشلًا من ثلاث نواحٍ: أولًا، التشفير ليس الوسيلة الأمثل لتخزين كلمات المرور؛ ثانيًا، يُسرّب وضع ECB المدخلات المتطابقة كمخرجات متطابقة؛ ثالثًا، إعادة استخدام مفتاح واحد عبر قاعدة البيانات بأكملها يعني أن فك تشفير المفتاح مرة واحدة يكفي لفك تشفير جميع السجلات البالغ عددها 153 مليون سجل. وصف شناير هذا الاختراق بأنه من أسوأ اختراقات كلمات المرور في التاريخ. وكان الحل في كل مرحلة هو التحوّل إلى التشفير البطيء المُملّح.
الملح مقابل الفلفل: الدفاع ذو الطبقتين
يُعدّ "الفلفل" بمثابة "الملح" الأقل شهرة. الفكرة هي: قيمة سرية إضافية تُضاف إلى كل كلمة مرور يعالجها التطبيق، ولكنها تُخزّن خارج قاعدة البيانات. قد تكون هذه القيمة متغيرًا بيئيًا، أو مدخلًا في خدمة إدارة المفاتيح، أو مفتاحًا موجودًا في وحدة أمان الأجهزة (HSM). يُخزّن "الملح" بجوار قيمة التجزئة (hash) كنص عادي، بينما لا يُخزّن "الفلفل" كذلك.
يتمثل نموذج التهديد في سرقة قاعدة البيانات فقط. فإذا سرق المهاجم قاعدة البيانات فقط - عبر حقن SQL، أو نسخة احتياطية مُهيأة بشكل خاطئ، أو تسريب لملف قاعدة البيانات - فإنه يمتلك الملح والتجزئة، لكنه يفتقر إلى مفتاح التشفير. وبدون مفتاح التشفير، لا يمكنه حتى البدء في تجربة جميع الاحتمالات الممكنة، لأن كل تخمين يقوم بتجزئة قاعدة البيانات يفتقر إلى مُعدِّل السر العام.
تُشغّل عملية التنفيذ النموذجية `argon2id(salt + password + pepper)`، أو بحذرٍ أكبر، تحسب `HMAC(pepper, password + salt)` أولًا ثم تُدخل النتيجة إلى Argon2id. توصي OWASP باستخدام pepper للأنظمة عالية القيمة، لكنها تُقرّ بالمفاضلة: فعملية تدوير pepper مُرهقة تشغيليًا. إذ يعني تدويرها إعادة تشفير كلمة مرور كل مستخدم عند تسجيل الدخول التالي، وإذا فُقدت pepper دون وجود نسخة احتياطية، يصبح التحقق من جميع الحسابات مستحيلًا. تتجاهل معظم تطبيقات المستهلكين استخدام pepper، بينما لا تستخدمه عادةً تطبيقات البنوك والجهات الحكومية وقطاع الرعاية الصحية.
التشفير الحديث لكلمات المرور في عام 2026
يُصنّف دليل OWASP لعام 2025 لتخزين كلمات المرور أربع خوارزميات حسب الأفضلية. جميع هذه الخوارزميات مُدمجة في خاصية Salt، فلا يتم توليدها يدويًا.
| الخوارزمية | الحد الأدنى لمتطلبات OWASP 2025 | المواصفات |
|---|---|---|
| Argon2id (مفضل) | m=19 ميجابايت، t=2، p=1 | RFC 9106 (2021) |
| سكريبت | N=2^17، r=8، p=1 | RFC 7914 (2016) |
| bcrypt (التقليدي) | التكلفة ≥ 10؛ سعة الإدخال 72 بايت | نيلز بروفوس، 1999 |
| PBKDF2-HMAC-SHA256 | 600,000 تكرار | RFC 2898؛ خاص بمعايير FIPS فقط |
يُعدّ Argon2id صعبًا من حيث استهلاك الذاكرة، ما يعني أن كل محاولة تخمين لا تتطلب دورات معالجة مركزية فحسب، بل تتطلب أيضًا جزءًا محددًا من ذاكرة الوصول العشوائي (RAM). ويعني الحد الأدنى الذي حددته OWASP وهو 19 ميجابايت لكل تجزئة، أن المهاجم الذي يبني شريحة ASIC مخصصة عليه أيضًا بناء ذاكرة سريعة كبيرة، والذاكرة هي الجزء المكلف في أي جهاز. يجمع متغير "id" بين Argon2i (المقاوم للهجمات الجانبية) وArgon2d (المقاوم لوحدات معالجة الرسومات) من خلال تشغيل Argon2i في النصف الأول وArgon2d في النصف الثاني.
يُعدّ scrypt أقدم من Argon2id ويعمل وفق نفس مبدأ استهلاك الذاكرة. أما bcrypt فهو أقدم وأبسط، وله حدّ أقصى للإدخال يبلغ 72 بايت، مما قد يُسبب مشاكل للتطبيقات التي تستخدم عبارات مرور طويلة - يُنصح باستخدام التجزئة المسبقة مع SHA-256 وتشفير base64 إذا كنت بحاجة إلى إدخالات أطول. يُعدّ PBKDF2 الخيار الأبطأ ولكنه متوافق مع معيار FIPS؛ وقد رفعت OWASP عدد التكرارات إلى 600,000 لـ SHA-256 في عام 2023، بعد أن كان 310,000.
ما لا ينبغي إدراجه في هذه القائمة: SHA-256 العادي، وSHA-512 العادي، وMD5، وSHA-1، وأي دالة مخصصة تنتهي بـ "+ salt". السرعة هي المعيار الحاسم. صُمم SHA-256 ليكون سريعًا على الأجهزة العادية، وهذا عكس ما تحتاجه أنظمة تخزين كلمات المرور.
أخطاء شائعة في عملية التمليح تظهر في عمليات التدقيق الحقيقية
تستمر تقارير الاختراقات في العالم الحقيقي في الإشارة إلى نفس الأخطاء القليلة.
إعادة استخدام قيمة ملح واحدة لكل مستخدم يُبطل الآلية برمتها، إذ تعود مشكلة جدول قوس قزح، ولكن بخطوة إضافية. استخدام اسم المستخدم كملح أسوأ، لأن أسماء المستخدمين تتكرر عبر الأنظمة، ويمكن حساب جداول قوس قزح مسبقًا للأسماء الشائعة. تبدأ أطوال الملح الأقل من 16 بايت في السماح بالتصادمات على نطاق قواعد المستخدمين الكبيرة. توليد الملح باستخدام دالة عشوائية غير تشفيرية - مثل `Math.random()`، `time(0)` mod something، وهي دالة توليد الأرقام العشوائية الافتراضية للغة - يُنتج قيمًا يمكن التنبؤ بها، مما يُفقد الملح فائدته.
خطأٌ آخر أكثر دقة هو تخزين قيمة الملح (Salt) على خادم مختلف "لأسباب أمنية". قيمة الملح ليست سرًا. توزيعها على أنظمة متعددة يُضيف تعقيدًا تشغيليًا دون أي تعزيز للقوة التشفيرية. خزّنها في نفس صف التجزئة (Hash). سلاسل PHC الحديثة تقوم بذلك تلقائيًا.
أكبر ثغرة أمنية، بحسب عمليات التدقيق لعام 2026، هي استخدام خوارزمية SHA-256 مع إضافة قيمة عشوائية (Salt) ثم إرسالها. تمنع القيمة العشوائية استخدام جداول قوس قزح، لكنها لا تُجدي نفعًا ضد مزارع وحدات معالجة الرسومات (GPU) التي تُجري عشرة مليارات عملية تخمين في الثانية الواحدة على حساب واحد. الحل ليس في إضافة قيمة عشوائية ثانية، بل في التحول إلى خوارزمية اشتقاق مفاتيح (KDF) بطيئة مثل Argon2id.
أخيرًا: التجزئات القديمة غير المُملّحة. التحديث إلزامي. النمط القياسي هو التحقق من التجزئة القديمة عند تسجيل الدخول التالي، وإعادة تجزئتها باستخدام الخوارزمية الحديثة، ثم استبدالها. بالنسبة للمستخدمين الذين لا يسجلون الدخول مرة أخرى، يُفرض إعادة تعيين كلمة المرور وفقًا لجدول زمني محدد.

لماذا لا يكفي التمليح وحده؟
التمليح طبقة حماية، وليس حصنًا منيعًا. فهو يصد هجومًا محددًا - وهو استخدام الجداول المحسوبة مسبقًا - ولا يكشف شيئًا عن قوة كلمة المرور الأساسية. لا تزال هجمات القوة الغاشمة فعالة ضد كلمات المرور الضعيفة. ولا تزال هجمات حشو بيانات الاعتماد فعالة ضد كلمات المرور المعاد استخدامها. ولا يزال التصيد الاحتيالي فعالًا ضد أي كلمة مرور.
تعتمد حماية كلمات المرور الحقيقية في عام 2026 على أربع آليات دفاعية. يتولى Argon2id، باستخدام قيمة عشوائية (Salt) بحجم 16 بايت لكل مستخدم، إدارة التخزين. أما "Pepper"، وهو إجراء اختياري ولكنه مفيد للأنظمة الحساسة، فيمنع سرقة قواعد البيانات فقط. ويمنع التحقق متعدد العوامل حشو بيانات الاعتماد ومعظم عمليات التصيد الاحتيالي. كما أن المراقبة المستمرة للاختراقات - مثل خدمة Have I Been Pwned وواجهة برمجة التطبيقات الخاصة بها - ترصد لحظة ظهور بيانات اعتماد المستخدم في أي تسريب، مما يُجبره على إعادة تعيينها.
إذا تم تجاوز أي طبقة من هذه الطبقات، فسيجد المهاجم الثغرة في نهاية المطاف. إن استخدام تقنية "Salting" وحدها، أو أي دفاع بمفرده، هو بالضبط ما حددته جميع تحليلات ما بعد الاختراقات في العقد الماضي كنقطة ضعف.