في مجال أمن التطبيقات، لا توجد مسؤوليات أكثر أهمية من التعامل مع بيانات اعتماد المستخدمين. لعقود من الزمان، اعتمدت الصناعة على دوال التجزئة أحادية الاتجاه السريعة مثل MD5 وSHA-1. ومع ذلك، مع تطور قدرات الأجهزة، لا سيما مع ظهور وحدات معالجة الرسومات (GPUs) وشرائح ASIC المتخصصة، أصبحت هذه الخوارزميات القديمة عفا عليها الزمن بشكل خطير. اليوم، تخزين كلمات المرور باستخدام تجزئة بسيطة يشبه إغلاق باب منزلك بخيط. يستكشف هذا المنشور استراتيجيات تجزئة كلمات المرور الحديثة، مع التركيز على دوال التجزئة التكيفية المصممة لمقاومة هجمات القوة الغاشمة.
المبادئ الأساسية لتخزين كلمات المرور بأمان
قبل الغوص في الخوارزميات المحددة، من الضروري فهم الأعمدة الثلاثة لتخزين كلمات المرور بأمان:
- الوظيفة أحادية الاتجاه: يجب أن يكون من المستحيل حسابياً عكس التجزئة لاستعادة كلمة المرور الأصلية.
- إضافة الملح (Salting): يجب دمج كل كلمة مرور مع سلسلة بيانات عشوائية وفريدة (الملح) قبل التجزئة. يمنع هذا هجمات جداول قوس قزح ويضمن أن المستخدمين الذين لديهم نفس كلمة المرور سيكون لديهم تجزئات مختلفة.
- القابلية للتكيف (عامل العمل): يجب أن تكون عملية التجزئة بطيئة ومتاحة للتكوين بشكل متعمد. يتيح ذلك للمطورين زيادة التكلفة الحسابية مع مرور الوقت مع تحسن الأجهزة، مما يجعل تكلفة الهجوم باهظة الثمن بالنسبة للمهاجمين.
المعيار الذهبي: bcrypt وArgon2
في الوقت الحالي، يُوصى بـ bcrypt و Argon2 كمعايير. Argon2 هو الفائز في مسابقة تجزئة كلمات المرور (PHC)، ويُفضل عادةً للمشاريع الجديدة بسبب طبيعته الصعبة في استخدام الذاكرة، مما يجعله مقاوماً للهجمات القائمة على وحدات معالجة الرسومات. يظل bcrypt مدعوماً على نطاق واسع وهو خيار آمن إذا لم يكن Argon2 متاحاً في مجموعة الأدوات الخاصة بك.
لماذا لا نستخدم SHA-256؟
غالباً ما يستخدم المطورون بشكل خاطئ SHA-256 أو SHA-512 لتخزين كلمات المرور. بينما تعتبر هذه تجزئات تشفيرية آمنة، إلا أنها مصممة لتكون سريعة. يمكن للمهاجم حساب مليارات تجزئات SHA-256 في الثانية على وحدة معالجة رسومات واحدة. على العكس من ذلك، تم تصميم خوارزميات تجزئة كلمات المرور لتكون بطيئة. فهي تتضمن معلمة "تكلفة" تحدد عدد التكرارات أو كتل الذاكرة المستخدمة، مما يبطئ كل من محاولات المصادقة المشروعة ومحاولات القوة الغاشمة الخبيثة.
التطبيق العملي في Python
لنلقِ نظرة على كيفية تنفيذ تجزئة كلمات المرور الآمنة باستخدام مكتبة passlib، والتي تجرد تعقيد المكتبات الأساسية مثل bcrypt أو argon2.
استخدام bcrypt
إليك مثال بلغة Python يوضح كيفية تجزئة كلمة المرور والتحقق منها مقابل تجزئة مخزنة. لاحظ أننا نستخدم مولداً ثابتاً للملح لضمان التفرد لكل كلمة مرور.
import bcrypt
def hash_password(plain_password: str) -> str:
# Generate a salt and hash the password
# bcrypt automatically handles the salt and includes it in the output
salt = bcrypt.gensalt(rounds=12)
hashed = bcrypt.hashpw(plain_password.encode('utf-8'), salt)
return hashed.decode('utf-8')
def verify_password(plain_password: str, hashed_password: str) -> bool:
# Check the provided password against the stored hash
return bcrypt.checkpw(plain_password.encode('utf-8'), hashed_password.encode('utf-8'))
# Example usage
password = "MySuperSecret123!"
hashed = hash_password(password)
print(f"Hashed Password: {hashed}")
# Verification
if verify_password(password, hashed):
print("Access Granted")
else:
print("Access Denied")
استخدام Argon2
يُعد Argon2id المتغير الموصى به، حيث يجمع بين مقاومة هجمات القنوات الجانبية والصلابة في استخدام الذاكرة المقاومة لوحدة معالجة الرسومات.
from argon2 import PasswordHasher
from argon2.exceptions import VerifyMismatchError
ph = PasswordHasher(
time_cost=3, # Number of iterations
memory_cost=65536, # Memory usage in KiB
parallelism=4, # Number of threads
hash_len=16, # Output hash length
salt_len=16 # Salt length
)
def hash_argon2(password: str) -> str:
return ph.hash(password)
def verify_argon2(password: str, hash: str) -> bool:
try:
ph.verify(hash, password)
return True
except VerifyMismatchError:
return False
# Example usage
h = hash_argon2("MySuperSecret123!")
print(f"Argon2 Hash: {h}")
print(verify_argon2("MySuperSecret123!", h))
أفضل الممارسات للمطورين
- لا تقم بتطبيق التشفير الخاص بك: استخدم دائماً المكتبات الراسخة. هجمات القنوات الجانبية في التطبيقات المخصصة شائعة.
- تعامل مع هجمات التوقيت: تأكد من أن دوال التحقق الخاصة بك تستخدم طرق مقارنة ثابتة الزمن. تتعامل معظم المكتبات الحديثة (مثل
bcryptوargon2) مع هذا داخلياً، ولكن إذا قمت ببناء منطق مخصص، كن حذراً. - استعد للتدوير: مع تطور المعايير، يجب أن تخطط لإعادة تجزئة كلمات المرور أثناء تسجيل دخول المستخدم إذا كانت التجزئة الحالية تستخدم خوارزمية أضعف أو عامل تكلفة أقل. يُعرف هذا بـ "إعادة التجزئة الكسولة".
- فرض سياسات قوية: بينما يحمي التجزئة قاعدة البيانات، فإن فرض سياسات قوية لكلمات المرور (الطول، التعقيد) يقلل من احتمالية نجاح الاختراق غير المتصل بالإنترنت في حالة حدوث خرق.
الخاتمة
تجزئة كلمات المرور ليست مهمة "إعدادها والنسيان". إنها تتطلب يقظة مستمرة مع زيادة قوة الحوسبة. من خلال الانتقال بعيداً عن التجزئات السريعة مثل SHA-256 واعتماد الخوارزميات الصعبة في استخدام الذاكرة مثل Argon2 أو التكيفية مثل bcrypt، يمكن للمطورين رفع المعيار بشكل كبير للمهاجمين. قم بتأمين بيانات اعتماد مستخدميك اليوم لمنع الكوارث في الغد.