دوال اشتقاق المفاتيح: مقارنة PBKDF2 وArgon2 وscrypt
قارن دوال اشتقاق المفاتيح للتشفير المبني على كلمة المرور. نقاط القوة لـ PBKDF2 وArgon2 وscrypt.
للمفاتيح المشتقة من كلمة المرور في 2026، Argon2id هو الاختيار الموصى به (فائز PHC وخيار OWASP الأول، يتصدى فعلياً لمهاجمي GPU وASIC)، وscrypt خيار متين ثانٍ (صارم في الذاكرة، منتشر على نطاق واسع في العملات المشفَّرة)، فيما يبقى PBKDF2-SHA-256 بـ 600,000+ تكرار مقبولاً للتوافق مع الأنظمة القائمة لكنه يوفر حداً أدنى من المقاومة لـ GPU. لتطبيقات نقل الملفات التي يدخل فيها المستخدمون كلمة مرور لحماية ملف مشترك، Argon2id بـ 3 تكرارات و64 ميجابايت ذاكرة و4 توازٍ هو الخط الأساسي الحديث. PBKDF2 لا يزال حياً لأنه مدمج في Web Crypto API ولا يستلزم تبعية WASM. إليك كيف يختلف الثلاثة ومتى يُلائم كل منهم.
جدول المقارنة
| الخاصية | PBKDF2 | scrypt | Argon2id | |---|---|---|---| | سنة الإدخال | 2000 (RFC 2898) | 2009 (RFC 7914) | 2015 (فائز PHC) | | صرامة الذاكرة | لا | نعم | نعم | | مرونة المعاملات | التكرارات فقط | N، r، p | الوقت، الذاكرة، التوازي | | مقاومة GPU | ضعيفة | معتدلة | قوية | | مقاومة ASIC | ضعيفة جداً | معتدلة | قوية | | أصلية في المتصفح (Web Crypto) | نعم | لا | لا | | توصية OWASP 2024 | بديل مقبول | مقبول | مفضَّل | | تكلفة المتصفح المعتادة (أجهزة حديثة) | 600,000 تكرار = ~500 مللي ثانية | N=2^17 = ~800 مللي ثانية | 3 تكرارات، 64 ميجابايت = ~1 ثانية |
لماذا تهم صرامة الذاكرة
نموذج التهديد للتشفير المبني على كلمة المرور هو القوة الغاشمة دون اتصال. يستطيع المهاجم الحصول على النص المشفَّر مع الملح ويمر عبر قاموس كلمات المرور محاولاً اشتقاق مفتاح يُعطي تشفيراً ناجحاً. الدفاع يقتضي جعل كل محاولة مُكلفة.
PBKDF2 يُكلّف كل محاولة في وقت المعالج فحسب (تكرارات SHA-256). وحدات GPU الحديثة تُجري مليارات عمليات SHA-256 في الثانية؛ بطاقة ألعاب يمكنها اختبار 10-100 مليون تخمين PBKDF2-SHA-256-600000 يومياً. مهاجمو ASIC يتفوقون بعدة مراتب.
دوال صرامة الذاكرة (scrypt وArgon2) تستلزم كمية ذاكرة ثابتة لكل محاولة. GPU وASIC لها نطاق ترددي محدود للذاكرة، فيتقيد التوازي لكل جهاز. متطلب ذاكرة 64 ميجابايت يعني أن GPU بذاكرة 16 جيجابايت تستطيع تشغيل 256 تخميناً موازياً كحد أقصى لا ملايين. يرتفع المتطلب الاقتصادي للقوة الغاشمة بمقدار 2-3 مراتب.
PBKDF2: الإعداد الافتراضي الموروث
PBKDF2 (RFC 2898) يُكرّر دالة شبه عشوائية، عادةً HMAC-SHA-256 أو HMAC-SHA-512، على كلمة المرور والملح. عدد التكرارات هو الضبط الوحيد.
const passwordKey = await crypto.subtle.importKey(
"raw", new TextEncoder().encode(password),
"PBKDF2", false, ["deriveKey"]
);
const aesKey = await crypto.subtle.deriveKey(
{
name: "PBKDF2",
salt, // 16 بايت عشوائي
iterations: 600000,
hash: "SHA-256",
},
passwordKey,
{ name: "AES-GCM", length: 256 },
false,
["encrypt", "decrypt"]
);
توصي OWASP 2023 بحد أدنى 600,000 تكرار لـ PBKDF2-SHA-256. بعض المواصفات (كالإعداد الافتراضي لـ LastPass عام 2018 بـ 100,100) تُعدّ منخفضة جداً في 2026.
المزايا: مدمجة في Web Crypto، بلا WASM، معتمدة بـ FIPS، مدعومة في استئناف جلسة TLS 1.3، تعمل في Node والمتصفحات بشكل متطابق.
القيود: لا صرامة في الذاكرة، عرضة لتسريع GPU وASIC. مضاعفة التكرارات تضاعف تكلفة المهاجم لكنها تضاعف أيضاً تكلفة المستخدم الشرعي. عند نقطة ما يرفض المستخدمون الانتظار فتضطر لتحديد سقف للتكرارات.
scrypt: أول نشر لصرامة الذاكرة
scrypt (RFC 7914) اخترعه Colin Percival عام 2009 لـ Tarsnap. يُمرّر مادة كلمة المرور عبر مخزن مؤقت ضخم في الذاكرة، مُلزِماً المهاجم بالاحتفاظ بذلك المخزن أثناء كل تخمين.
ثلاثة معاملات:
- N: عامل التكلفة (عادةً 2^14 إلى 2^20). استخدام الذاكرة تقريباً 128 × N × r بايت.
- r: حجم الكتلة (عادةً 8). يؤثر على الذاكرة وعدد تكرارات GHASH.
- p: التوازي (عادةً 1). القيم الأعلى تسرّع الحوسبة الشرعية لكن تسرّع المهاجمين أيضاً؛ اتركه عادةً عند 1.
توصي OWASP بـ N=2^17، r=8، p=1 كخط أساسي، يستهلك ~128 ميجابايت ويعمل في نحو 800 مللي ثانية على الأجهزة الحديثة.
scrypt ليس في Web Crypto API. في JavaScript، استخدم scrypt-js أو @noble/hashes أو libsodium.js. تستخدم Litecoin وDogecoin تحديداً scrypt كإثبات عمل، مما حفّز تطوير ASIC خاص بـ scrypt وأضعف بعضاً من ميزته الأصلية ضد ASICs.
Argon2id: الإعداد الافتراضي لـ 2026
فاز Argon2 بمسابقة تجزئة كلمات المرور عام 2015. ثلاثة متغيرات: Argon2d (الأسرع، معتمد على البيانات، عرضة للهجوم بالقناة الجانبية)، وArgon2i (مستقل عن البيانات، أبطأ)، وArgon2id (هجين، موصى به لمعظم الاستخدامات). قنّن RFC 9106 عام 2021.
ثلاثة معاملات:
- t (الوقت): تكرارات عبر الذاكرة. عادةً 2-3.
- m (الذاكرة): الذاكرة بالكيلوبايت. عادةً 65536 (64 ميجابايت) أو أعلى.
- p (التوازي): درجة التوازي. عادةً 1-4.
الخط الأساسي لـ OWASP 2024: t=2، m=19456 (19 ميجابايت)، p=1 كحد أدنى، وt=3، m=65536 (64 ميجابايت)، p=4 لحماية أقوى.
import { argon2id } from '@noble/hashes/argon2';
import { utf8ToBytes } from '@noble/hashes/utils';
const derivedKey = argon2id(utf8ToBytes(password), salt, {
t: 3, m: 65536, p: 4, dkLen: 32
});
أو عبر argon2-browser (WASM):
import argon2 from 'argon2-browser';
const hash = await argon2.hash({
pass: password, salt,
type: argon2.ArgonType.Argon2id,
time: 3, mem: 65536, parallelism: 4, hashLen: 32
});
يتصدى Argon2id لمهاجمي GPU بفاعلية أكبر من scrypt لأن نمط وصوله للذاكرة أقل ملاءمةً لتصاميم الذاكرة الضخمة. توجد ASICs لـ Argon2 في البحوث لكنها لم تُنشر اقتصادياً على نطاق المهاجمين بعد.
اختيار المعاملات لتطبيقك
طريقة المعايرة: اختر أطول انتظار يتحمله مستخدموك (عادةً 500 مللي ثانية إلى ثانيتَين)، وقِس على أبطأ جهاز مستهدف، واضبط المعاملات لتحقيق ذلك.
لمشاركات الملفات المحمية بكلمة مرور بنمط HexaTransfer، حيث يحدث الاشتقاق مرة واحدة عند الرفع ومرة عند التنزيل، ثانية إلى ثانيتَين مقبولتان. المعاملات:
- PBKDF2-SHA-256: 600,000-1,200,000 تكرار
- scrypt: N=2^17، r=8، p=1
- Argon2id: t=3، m=65536، p=4
لأنظمة تسجيل الدخول حيث ينتظر المستخدم بعد كتابة كلمة المرور، السقف الأمثل لتجربة المستخدم هو 300-500 مللي ثانية. تنقص المعاملات بالنصف تقريباً. للسيناريوهات الدفعية غير المتزامنة، ارفع إلى 3-5 ثوانٍ.
إدارة الملح
كل دالة KDF تحتاج ملحاً. القواعد:
- 16 بايت عشوائي كحد أدنى
- يُولَّد عبر
crypto.getRandomValues()لاMath.random()أبداً - فريد لكل كلمة مرور (إن استخدمت Alice وBob كلمة المرور ذاتها يجب أن يختلف ملحاهما)
- غير سري — خزّنه بجانب النص المشفَّر
يُناقَش أحياناً استخدام "الفلفل" (سر مضاف إلى كل الاشتقاقات). لنقل الملفات حيث "الخادم" مجرد مخزن بيانات ثنائي، لا قيمة مضافة للفلفل لعدم وجود سر من جانب الخادم. للأنظمة المبنية على حسابات، يجعل الفلفل المُخزَّن منفصلاً عن قاعدة كلمات المرور الاختراقات أقل إفادةً للمهاجمين.
الانتقال بين دوال KDF
إن كان لديك نشر قائم على PBKDF2 وتريد الانتقال إلى Argon2id:
- خزّن معرّف KDF في بيانات وصف النص المشفَّر (
"kdf": "pbkdf2-sha256-600000"أو"kdf": "argon2id-3-65536-4") - في الرفعات الجديدة استخدم Argon2id
- عند فكّ التشفير اقرأ معرّف KDF واستخدم الدالة المقابلة
- لا ترقِّ النصوص المشفَّرة القديمة بشكل أعمى؛ ستحتاج كلمة المرور لإعادة الاشتقاق
مرّت LastPass و1Password وBitwarden جميعها بهذا الانتقال. الثلاثة تعتمد افتراضياً الآن على PBKDF2 بـ 600,000+ تكرار مع توفر Argon2id في الإصدارات الأحدث. نعم، حتى مديرو كلمات المرور كانوا بطيئين في تبني Argon2 — وهو ينتشر تدريجياً لأن أدوات النظام البيئي احتاجت وقتاً للنضج.
ماذا عن bcrypt؟
bcrypt (1999) دالة تجزئة كلمات مرور جيدة بصرامة متواضعة في الذاكرة. تقطع المدخلات عند 72 بايتاً (خطأ شهير — كلمات المرور الطويلة تُبتر صامتةً قبل جولتَي 2011). الإعداد الافتراضي التاريخي في Ruby on Rails وكثير من إطارات PHP. للكود الجديد في 2026 فضّل Argon2id؛ bcrypt مناسب للحفاظ على الأنظمة القائمة.
التوصية الواقعية
لخدمة نقل ملفات جديدة في 2026:
- إن استطعت شحن تبعية بحجم 15-200 KB: Argon2id عبر @noble/hashes أو libsodium.js
- إن احتجت صفر تبعيات وتطرف في حجم الحزمة: PBKDF2-SHA-256 بـ 600,000 تكرار عبر Web Crypto
- إن كنت تكتب محفظة عملات مشفَّرة أو أي شيء يرث scrypt قديماً: scrypt بـ N=2^17
لتطبيقات الإنتاج التي تتعامل مع ملفات حساسة، Argon2id يستحق تبعية WASM. للمشاركات البسيطة المحمية بكلمة مرور حيث يولّد المستخدمون كلمة مرور عشوائية على أي حال، PBKDF2 كافٍ لأن الإنتروبيا في كلمة المرور لا في KDF.
جرّبها على hexatransfer.com — مجاني، بدون حساب، حتى 10 جيجابايت.
أرسل ملفات كبيرة بأمان مع تشفير من طرف إلى طرف
انقل ملفات حتى 10 جيجابايت مجاناً مع تشفير من طرف إلى طرف. لا حاجة لحساب. يتم تشفير ملفاتك في متصفحك قبل الرفع — لا أحد آخر يستطيع قراءتها.
إرسال ملف