
The hmac-bcrypt password hashing function
يحتوي هذا المستودع على تطبيقات مرجعية لدالة تجزئة كلمات المرور hmac-bcrypt بعدة لغات. يحاول كل تطبيق مرجعي أن يكون نقلًا بنسبة 1:1 من التطبيقين الأصليين بلغة C وPerl اللذين أنشأهما @epixoip حيثما أمكن، وهي متوافقة تمامًا مع بعضها البعض (أي أنها تُنتج وتتحقق من نفس قيم التجزئة.)
يُعرّف كل تطبيق مرجعي دالتين إجرائيتين بالنماذج الأولية الزائفة التالية:
string hmac_bcrypt_hash(password, settings?, pepper?)
boolean hmac_bcrypt_verify(password, expected, pepper?)
يُرجى الرجوع إلى حالات الاختبار المرفقة مع كل تطبيق مرجعي لمعرفة كيفية دمج واستخدام هذه الدوال في مشروعك. تم اختيار واجهة إجرائية من أجل البساطة، ولكن يمكنك بحرية دمج هذه الدوال في أصناف أو كائنات كما تشاء.
تشير معلمة settings في هذا السياق إلى سلسلة إعدادات bcrypt قياسية تحتوي على معرّف التجزئة (2a)، وتكلفة log2 (مثل 13)، وقيمة ملح اختيارية بطول 22 بايت مرمّزة بـ radix64 (مثل LhayLxezLhK1LhWvKxCyLO). تُسلسَل هذه القيم معًا في سلسلة مفصولة بعلامة الدولار؛ مثل $2a$13$LhayLxezLhK1LhWvKxCyLO.
معلمة settings اختيارية؛ وفي أغلب الأحيان ينبغي تركها فارغة/null لاستخدام التكلفة الافتراضية 13 وملح مُولَّد. وعلى الأكثر، إذا رغبت في استخدام قيمة تكلفة غير 13، يمكنك توفير المعرّف + قيمة التكلفة فقط (مثل $2a$10$). لا يُنصح بإنشاء وتوفير قيم الملح بنفسك!
تُعرّف معلمة pepper سرًا مشتركًا عامًا وهي اختيارية بالمثل؛ إذا كانت فارغة/null، تُستخدم القيمة الافتراضية hmac_bcrypt. تُستخدم في المقام الأول للدفاع ضد هجمات shucking، ولكن يمكن استخدامها أيضًا لزيادة الأمان وصعوبة وتكلفة الاختراق (خاصة عند استخدامها مع HSM).
توظف دالة تجزئة كلمات المرور hmac-bcrypt خوارزمية bcrypt مع تجزئة مسبقة ولاحقة مناسبة، مدموجة مع pepper اختياري. في الكود الزائف، يكون الأمر مباشرًا إلى حد كبير:
pre_hash = hmac_sha512_base64(password, pepper)
mid_hash = bcrypt(pre_hash, settings)
post_hash = hmac_sha512_base64(mid_hash, pepper)
return settings + post_hash
تُستخدم التجزئة المسبقة لتمكين أطوال إدخال أكبر من الحد الأقصى لـ bcrypt البالغ 72 بايت. تم اختيار SHA-512 نظرًا لحجم كلمتها البالغ 64 بت، وهو أمر ملائم للمدافعين على CPU ولكنه يعيق المهاجمين على GPU. ومع ذلك، لا يمكن استخدام قيمة SHA-512 خام لعدة أسباب:
للتخفيف من هجمات shucking، يجب أن تكون التجزئة المسبقة مملّحة — أو في هذه الحالة، مفلفلة (peppered) — وتوفر HMAC وسيلة ملائمة لتزويد التجزئة بمفتاح. تُرمَّز قيمة HMAC الناتجة بعد ذلك بـ base64 لإنتاج إدخال ASCII سفلي نظيف يخفف من مشاكل البايتات الصفرية والبيانات الثنائية.
سيلاحظ القارئ المُدقّق أن hmac_sha512_base64 تُنتج 88 بايتًا من البيانات، بينما يبلغ الحد الأقصى لحجم إدخال bcrypt 72 بايتًا. هذه ليست مشكلة، بل إنها في الواقع مفضلة على استخدام خوارزمية تجزئة تُنتج بيانات إدخال أقل مثل sha256. نريد ملء جميع البايتات الـ 72، ولا يُفقَد أي أمان عند اقتطاع sha512 إلى 432 بتًا (وهي أكبر من الـ 384 بتًا التي يوفرها sha384).
تُستخدم التجزئة اللاحقة بشكل أساسي لتمييز تجزئات hmac-bcrypt عن تجزئات bcrypt — أي أن الأطوال ستختلف — ولكن أيضًا لإضافة طبقة حماية إضافية بفضل الـ pepper. يمكن حتى تنفيذ خطوة التجزئة اللاحقة بقيمة pepper مخزنة في HSM (موصى بها بشدة!) لمزيد من الحماية.
في حين أن صلابة الذاكرة كانت تجربة مثيرة للاهتمام، فإن المسار الصحيح لتحقيق مقاومة التسريع هو بوضوح تام صلابة الكاش. تستمر سرعات الذاكرة وعرض النطاق في الازدياد، بينما تصبح RAM أكبر وأرخص وأكثر كثافة. لكن أحجام الكاش وسرعات الكاش وتكاليف الكاش ثابتة نسبيًا. حتى تعليمات scatter/gather العتادية لم تُحدث التأثير الدراماتيكي الذي توقعنا يومًا أنها قد تُحدثه على خوارزميات الكاش الصلبة.
أفضل خوارزميات صلابة الذاكرة — Argon2 وscrypt — هي في الواقع أقل مقاومة للتسريع من خوارزميات صلابة الكاش لزمن تشغيل مستهدف أقل من 1000ms، مما يجعلها KDF رائعة ولكنها ليست رائعة في المصادقة في الزمن الحقيقي.
من الناحية المثالية، سيستخدم المرء دالة تجزئة كلمات مرور صلبة الكاش بشكل مقصود، مثل pufferfish أو bscrypt. ومع ذلك، فإن هذه الدوال أحدث وأقل دراسة ويتوفر لها عدد قليل من المكتبات. أما bcrypt — رغم كونها صلبة الكاش عن غير قصد — فهي متاحة بسهولة لكل لغة وإطار عمل تقريبًا. من بين الخوارزميات المتاحة لنا بسهولة، توفر bcrypt أكبر مقاومة للتسريع للمصادقة التفاعلية في الزمن الحقيقي (زمن تشغيل مستهدف < 1000ms)، لذا فإن الإجابة الواضحة إذن هي الاستفادة من bcrypt المتاحة لدينا.
ومع ذلك، فإن bcrypt لديها بعض القيود الملحوظة، كما يسارع منتقدوها الصاخبون إلى الإشارة:
تعالج hmac-bcrypt كلتا هاتين المشكلتين، والمزيد.