مقدمة: لماذا المصادقة الآمنة ليست خيارًا بل ضرورة
أيها الأصدقاء، تخيلوا المشهد: لقد كتبتم تطبيق C++ رائعًا — خادم دردشة، API لمتجر إلكتروني، أو حتى قاعدة بيانات بسيطة للعملاء. كل شيء يعمل، والمستخدمون سعداء. وفجأة — بام! — شخص ما سرق قاعدة بيانات كلمات المرور. تسريب على الإنترنت، سمعة صفرية، والمستخدمون في ذعر. هل يبدو الأمر مألوفًا؟ للأسف، هذه قصة آلاف الشركات الناشئة والعمالقة. والسبب هو أن المصادقة الآمنة في تطبيقات C++ تم تنفيذها "على عجل".
في هذه المقالة، لن نلقي محاضرات مملة. سنشرح كيفية حماية دخول المستخدمين في مشروع C++ الخاص بك بشكل صحيح. ستتعرف على لماذا تخزين كلمات المرور بنص واضح هو خطيئة مميتة، وكيفية استخدام التجزئة بشكل صحيح، وكيفية الحماية من الهجمات الأكثر شيوعًا. هيا بنا!
أساسيات الأمان: ثلاث ركائز يقوم عليها كل شيء
قبل كتابة الكود، دعونا نفهم ما يعنيه "المصادقة الآمنة" حقًا. إنها ليست مجرد "التحقق من اسم المستخدم وكلمة المرور". إنها فلسفة كاملة تتكون من ثلاثة مبادئ رئيسية:
- لا تخزن كلمات المرور بنص واضح أبدًا. حتى لو سرق المخترق قاعدة البيانات، يجب أن يحصل على مجموعة غير مفيدة من الرموز.
- استخدم "الملح" (salt). كلمات المرور المتطابقة لمستخدمين مختلفين يجب أن تعطي تجزئات مختلفة. هذا يقتل الجداول قوس قزح.
- احمِ قناة النقل. يجب ألا تنتقل كلمة المرور عبر الشبكة بنص واضح. استخدم HTTPS أو التشفير على مستوى البروتوكول.
الآن دعنا ننتقل إلى التطبيق العملي. سنبني نظام مصادقة المستخدمين في C++ باستخدام مكتبات التشفير الحديثة.
الخطوة 1: تجزئة كلمات المرور — اختيار الخوارزمية الصحيحة
انسَ MD5 و SHA-1. هذا من الماضي. لتخزين كلمات المرور بشكل آمن في C++، تحتاج إلى خوارزميات بطيئة ومقاومة للهجمات: bcrypt، scrypt أو Argon2 (الأخير هو الفائز في مسابقة PHC).
سنستخدم bcrypt — فهو بسيط وموثوق، وهناك مكتبة ممتازة libbcrypt أو bcrypt-cpp. قم بتثبيتها عبر مدير الحزم الخاص بك (vcpkg، conan أو قم ببنائها يدويًا).
مثال: تجزئة كلمة المرور باستخدام bcrypt
#include <iostream>#include <string>#include <bcrypt/bcrypt.h> // لنفترض هذا الهيكل
// دالة لتجزئة كلمة المرورstd::string hashPassword(const std::string& password) { // توليد "الملح" (عادةً bcrypt يفعل ذلك تلقائيًا) char salt[BCRYPT_HASHSIZE]; char hash[BCRYPT_HASHSIZE]; // توليد الملح (قد تختلف الدالة الحقيقية) bcrypt_gensalt(12, salt); // 12 جولة — توازن جيد بين السرعة والأمان // تجزئة كلمة المرور bcrypt_hashpw(password.c_str(), salt, hash); return std::string(hash);}
int main() { std::string userPassword = "MySuperP@ssw0rd!"; std::string hashed = hashPassword(userPassword); std::cout << "تجزئة كلمة المرور: " << hashed << std::endl; return 0;}لاحظ: الملح مدمج بالفعل في التجزئة. bcrypt يولد ملحًا فريدًا لكل كلمة مرور. هذه هي الحماية من هجمات التخمين باستخدام جداول قوس قزح.
التحقق من كلمة المرور عند تسجيل الدخول
عندما يدخل المستخدم كلمة المرور، لا يمكننا "فك تجزئتها" (التجزئة هي دالة باتجاه واحد). بدلاً من ذلك، نقارن تجزئة كلمة المرور المدخلة مع تلك المخزنة في قاعدة البيانات:
bool verifyPassword(const std::string& password, const std::string& storedHash) { // bcrypt_checkpw ترجع 0 إذا تطابقت كلمة المرور return (bcrypt_checkpw(password.c_str(), storedHash.c_str()) == 0);}
// مثال على الاستخدام في كود المصادقةstd::string userInput = "MySuperP@ssw0rd!";