Bcrypt في PHP: كيفية تشفير كلمات المرور بشكل صحيح وسريع
\n\nإذا كنت قد تساءلت يومًا "How do you use bcrypt for hashing passwords in PHP؟"، فأنت لست وحدك. هذا السؤال على Stack Overflow حصد آلاف المشاهدات - وليس بدون سبب. تشفير كلمات المرور هو أساس أمان أي تطبيق ويب، ولا يزال bcrypt واحدًا من أكثر الخوارزميات موثوقية وشعبية. في هذه المقالة، سنشرح كيفية استخدام bcrypt في PHP، وكيفية ضبطه لتحقيق أقصى أداء وتجنب الأخطاء الشائعة.
\n\nلماذا bcrypt بالتحديد؟ لأنه مقاوم لهجمات التخمين (brute-force) بفضل "الملح" المدمج (salt) وقابلية ضبط درجة التعقيد. ولكن كيف تجعل موقعك لا يبطئ عند كل تسجيل دخول؟ هذا ما سنناقشه.
\n\nما هو bcrypt ولماذا هو أفضل من MD5 أو SHA1؟
\n\nدعنا نكون واضحين من البداية: لا تستخدم أبدًا MD5 أو SHA1 لتشفير كلمات المرور. هذه الخوارزميات صُممت للسرعة في الحساب، وليس للأمان. أما bcrypt، فمصمم ليكون بطيئًا عن قصد. يستخدم cost factor (عامل التكلفة) الذي يحدد عدد مرات تكرار التشفير. كلما زاد cost factor، زاد الوقت اللازم لحساب التجزئة - وزادت صعوبة تخمين كلمة المرور على المهاجم.
\n\nفي PHP، تم تبسيط العمل مع bcrypt بشكل كبير بفضل الدوال password_hash() و password_verify(). ظهرت هذه الدوال في PHP 5.5 وأصبحت منذ ذلك الحين المعيار الفعلي.
كيفية استخدام bcrypt في PHP: مثال أساسي
\n\nلنبدأ بشيء بسيط. إليك كيفية تسجيل مستخدم وحفظ كلمة المرور الخاصة به:
\n\n<?php\n// تسجيل مستخدم جديد\n$password = "MySuperP@ss123";\n$hash = password_hash($password, PASSWORD_BCRYPT);\n\n// احفظ $hash في قاعدة البيانات (مثلاً في حقل password_hash)\necho $hash; // سيطبع شيئًا مثل $2y$10$...\n?>\n\nوإليك كيفية التحقق من كلمة المرور عند تسجيل الدخول:
\n\n<?php\n// تسجيل دخول المستخدم\n$loginPassword = "MySuperP@ss123";\n$storedHash = "$2y$10$..."; // من قاعدة البيانات\n\nif (password_verify($loginPassword, $storedHash)) {\n echo "كلمة المرور صحيحة!";\n} else {\n echo "كلمة المرور خاطئة.";\n}\n?>\n\nالأمر بسيط، أليس كذلك؟ لكن الشيطان يكمن في التفاصيل. دعنا نتعمق في cost factor.
\n\nضبط cost factor: التوازن بين الأمان والسرعة
\n\nافتراضيًا، يستخدم PASSWORD_BCRYPT cost factor = 10. هذا يعني 2^10 = 1024 تكرارًا. على خادم حديث، يستغرق هذا حوالي 0.1-0.2 ثانية. قد يبدو هذا قليلاً، ولكن إذا كان لديك 1000 عملية تسجيل دخول متزامنة - سيبدأ الوقت في التزايد.
كيف تختار cost factor الأمثل؟ هناك قاعدة بسيطة: يجب أن يكون بحيث لا يستغرق تشفير كلمة مرور واحدة أكثر من 0.5 ثانية على خادمك. يمكنك اختبار ذلك باستخدام الدالة password_hash() بقيم مختلفة.
إليك مثال لاختبار الأداء:
\n\n<?php\n$password = "test_password";\n$times = [];\n\nfor ($cost = 8; $cost <= 14; $cost++) {\n $start = microtime(true);\n password_hash($password, PASSWORD_BCRYPT, ['cost' => $cost]);\n $times[$cost] = microtime(true) - $start;\n}\n\nprint_r($times);\n?>\n\nعلى الاستضافة المشتركة النموذجية، سيكون cost factor بين 10-12 هو الأمثل. إذا كان لديك خادم قوي، يمكنك رفعه إلى 13-14. لكن لا تبالغ: cost factor مرتفع جدًا قد يؤدي إلى استهلاك كل موارد الخادم في التشفير أثناء هجوم.
\n\nتحسين أداء bcrypt في PHP
\n\nالآن ننتقل إلى الجزء الأكثر إثارة - كيف تجعل bcrypt أسرع دون التضحية بالأمان. إليك بعض الاستراتيجيات المجربة:
\n\n1. تخزين النتائج مؤقتًا (Caching)
\nإذا أدخل المستخدم كلمة مرور صحيحة، لماذا تعيد تشفيرها مع كل طلب؟ يمكنك تخزين النتيجة مؤقتًا لفترة قصيرة (مثلاً 5 دقائق) باستخدام Redis أو Memcached. هذا مفيد بشكل خاص