كلمات المرور تحت المجهر: لماذا لم تعد الطرق القديمة مجدية
\nتخيل: أنت مطور يكتب نظام تسجيل. يبدو الأمر بسيطًا، أليس كذلك؟ تأخذ كلمة المرور، تمررها عبر md5، وتخزنها في قاعدة البيانات. لكن في عام 2025، هذا النهج هو طريق مباشر للثغرات الأمنية. الهجمات الحديثة، GPU-بروتفورس، والجداول قوس قزح تحول الهاشات الضعيفة إلى غبار في ثوانٍ. سؤال من Stack Overflow بآلاف المشاهدات — «Secure hash and salt for PHP passwords» — لا يزال ملحًا، وسنحسمه نهائيًا.
\nفي هذه المقالة، ستتعلم كيفية هاش كلمات المرور بشكل صحيح في PHP باستخدام الخوارزميات الحديثة، والدوال المدمجة، والملح (salt). سنقوم بتكييف أفضل إجابات المجتمع لمحتوى تعليمي ونوضح لك كيفية حماية المستخدمين حتى في عام 2025.
\n\nلماذا md5 و sha1 شريرتان
\nإذا كنت لا تزال تستخدم md5 أو sha1 لتخزين كلمات المرور — توقف. هذه الخوارزميات صُممت للسرعة، وليس للأمان. في عام 2025، يمكن لوحدة معالجة الرسوميات (GPU) اختبار مليارات هاشات md5 في الثانية. إضافة الملح (سلسلة عشوائية) لا ينقذ: يتم تجاوز الجداول قوس قزح، لكن السرعة تظل قاتلة.
\n- \n
- Md5: 2^128 احتمال — يتم اختراقها في دقائق. \n
- Sha1: أفضل قليلاً، لكنها قديمة أيضًا. \n
- ملح بدون إبطاء: إذا كان الهاش سريعًا، فإن الملح يؤخر الهجوم فقط. \n
بدلاً من ذلك، نحتاج إلى خوارزميات «بطيئة» — تلك التي تتطلب وقتًا وذاكرة. هذه هي بالضبط ما تستخدمه password_hash.
password_hash و password_verify: الحل المدمج من PHP
\nمنذ PHP 5.5، ظهرت دالتان تحلان 90% من مشاكل أمان كلمات المرور: password_hash و password_verify. تقومان تلقائيًا بتوليد ملح آمن تشفيريًا وتستخدمان خوارزميات مقاومة للبروتفورس. في عام 2025، هذا هو المعيار، ولا داعي للاختراعات اليدوية!
كيف يعمل هذا؟
\nتأخذ الدالة password_hash كلمة المرور والخوارزمية (الافتراضي هو bcrypt، لكن يمكنك تحديد argon2). تُرجع سلسلة تحتوي بالفعل على الملح والمعاملات. لا تحتاج إلى تخزين الملح بشكل منفصل — فهو داخل الهاش.
<?php\n// هاش كلمة المرور\n$password = "SuperSecret123!";\n$hash = password_hash($password, PASSWORD_DEFAULT);\n\necho $hash; // $2y$10$... (60 حرفًا)\n?>\n\nالآن نتحقق من كلمة المرور عند تسجيل الدخول:
\n<?php\n$inputPassword = "SuperSecret123!";\n$storedHash = "$2y$10$..."; // من قاعدة البيانات\n\nif (password_verify($inputPassword, $storedHash)) {\n echo "كلمة المرور صحيحة!";\n} else {\n echo "كلمة المرور خاطئة.";\n}\n?>\n\nكل شيء بسيط ببراعة. تقوم password_verify تلقائيًا باستخراج الملح من الهاش والتحقق من كلمة المرور. لا حاجة لأي إجراءات إضافية.
اختيار الخوارزمية: bcrypt مقابل argon2
\nفي عام 2025، لديك خياران رئيسيان:
\n- \n
- Bcrypt (PASSWORD_BCRYPT): مجرّب عبر الزمن، يُستخدم افتراضيًا. مقاوم للهجمات، لكنه يتطلب ضبط cost factor. \n
- Argon2 (PASSWORD_ARGON2I أو PASSWORD_ARGON2ID): الفائز في مسابقة Password Hashing Competition. أكثر حداثة، يتطلب ذاكرة أكبر، مما يصعّب الهجمات على GPU. موصى به للمشاريع الجديدة. \n
مثال مع argon2:
\n<?php\n$hash = password_hash($password, PASSWORD_ARGON2ID, [\n 'memory_cost' => 1 << 17, // 128 MB\n 'time_cost' => 4,\n 'threads' => 2\n]);\n?>\n\nالمعامل memory_cost هو حجم الذاكرة بالكيلوبايت. كلما زاد، زاد الأمان، لكنه أبطأ. للإنتاج، اختبر على خادمك.
الملح (salt): كيف يعمل ولماذا لا تحتاجه بشكل منفصل
\nيسأل الكثير من المبتدئين: «كيف أضيف الملح يدويًا؟». الإجابة: لا تفعل. تقوم password_hash بتوليد 22 حرفًا من الملح العشوائي (لـ bcr