الدالة ‎crypt()‎ في PHP

من موسوعة حسوب

(PHP 4, PHP 5, PHP 7)

تُشفِّر الدالة ‎crypt()‎ سلسلةً نصيةً بطريقة غير قابلة للعكس.

الوصف

string crypt ( string $str [, string $salt ] )

تُعيد الدالة crypt()‎ هاش (hash) السلسلة النصية بإستعمال خوارزمية Unix DES أو أي خوارزمية أخرى متوفرة بالنظام.

على الرغم من أنَّ ضبط المعامل salt في الدالة crypt()‎ هو أمرٌ اختياري، إلا أن عدم ضبط قيمته سيؤدي إلى إنشاء هاش ضعيف للسلسة النصية. تُطلِق نسخ 5.6 للغة PHP وما بعدها الخطأ ‎E_NOTICE عند عدم ضبط المعامل ‎salt. لذلك احرص دائمًا على تحديد قيمة «قوية» بما فيه الكفاية للمعامل salt للحصول على أعلى درجة أمان.

تستعمل الدالة ‎‎password_hash()‎ هاش قوي وتُعيد معامل ‎salt قوي أيضًا.

الدالة password_hash()‎ هي نسخة مبسطة من الدالة ‎crypt()‎ متوافقة مع دوال الهاش لكلمات السر المتوفرة؛ لذلك يُحثّ على استعمال الدالة ‎password_hash()‎.

تدعم بعض أنظمة التشغيل عدة أنواع من الهاشات. تُستَبدل أحيانًا الخوارزمية المبنية على معيار تشفير البيانات DES بخوارزمية مبنية على معيار ‎MD5. يُختار نوع الهاش حسب قيمة المعامل ‎salt. قبل النسخة 5.3 كانت لغة PHP تحدد الخوارزميات المتوفرة وقت التثبيت اعتمادًا على الدالة crypt()‎ الموجودة في نظام التشغيل. إذا لم يُضبَط المعامل ‎salt فإن لغة ‎PHP تحدد قيمة تلقائية للمعامل ‎salt مكونة من 12 حرفًا عند إستعمال معيار ‎MD5 وتوافر استخدام الخوارزمية MD5 مع الدالة crypt()‎، وسيُستعمل معيار تشفير البيانات (DES) بمعامل ‎salt مكون من حرفين. تُحدد لغة ‎PHP معاملًا ثابتًا يُسمى CRYPT_SALT_LENGTH يدلُ على أكبر عدد مسموح به من الحروف للمعامل ‎salt في دوال الهاش المتوفرة.

تُعيد الدالةُ ‎‎crypt()‎ المستندة على معيار DES المعاملَ ‎salt في أول حرفين من السلسلة النصية المعادة. وتستعمل الدالة أول ثمانية محارف للمعامل str فقط، لذلك ستعيد السلاسل النصية الطويلة التي تملك أول ثمانية محارف متطابقة نفس القيمة باستعمال نفس المعامل ‎salt.

تكون قيمة المعاملات الثابتة التالية مساوية للقيمة 0 أو 1 حسب توفر نوع الهاش من عدمه في الأنظمة التي تدعم فيها الدالة crypt()‎ خيارات عدة لنوع الهاش:

  • CRYPT_STD_DES: خوارزمية هاش مبنية على معيار ‎DES باستعمال معامل salt مكون من حرفين مختارين من المجال "‎./0-9A-Za-z". إن استعمال أي حرف لا ينتمي إلى المجال المُعَرَف سيؤدي إلى فشل الدالة ‎crypt()‎.
  • CRYPT_EXT_DES: هي إضافة لخوارزمية الهاش المبنية على معيار DES. إذ يتكون المعامل salt من سلسلة نصية من 9 محارف تبدأ بشرطة سفلية (underscore) تتبعها 4 بايتات تمثل عدد التكرارات و تليها 4 بايتات أخرى تمثل قيمة المعامل salt. تُرَمز الأحرف بأحرف قابلة للطباعة، كل حرف يكتب بإستعمال 6 بت مع كتابة الحرف الأقل أهمية (least significant character) أولًا. تُرمَّز القيم من 0 إلى 63 على شكل "‎./0-9A-Za-z". استعمال أي حرف لا ينتمي إلى هذا المجال المعرف يؤدي إلى فشل الدالة ‎crypt()‎.
  • CRYPT_MD5: خوارزمية هاش مبنية على معيار MD5، بإستعمال معامل ‎salt مكون من 12 حرفا يبدأ بالقيمة ‎$1$.
  • CRYPT_BLOWFISH: يُحدد نوع هاش بإستعمال خوارزمية Blowfish. تكون قيمة المعامل salt سلسلة نصية منسقة كما يلي:"$2a$" أو "$2x$" أو "$2y$" ومعامل من حرفين و "$" و 22 حرفًا من الأحرف الأبجدية "‎"./0-9A-Za-z.  تعيد الدالة ‎crypt()‎ سلسلة نصية طولها 0 عند استخدام محارف خارج مجال المعامل salt. تدعم إصدارات لغة ‎PHP قبل نسخة 5.3.7 البادئة "$2a$" للمعامل salt فقط. قدمت النسخة 5.3.7 البادئات الجديدة لإصلاح ضعف الأمن في تنفيذ خوارزمية ‎Blowfish. يمكن الرجوع إلى هذا المستند للإطلاع على تفاصيل الإصلاحات الأمنية كاملة. ننصح المطورين الذين يستهدفون النسخة 5.3.7 فما فوق بإستخدام البادئة  "$2y$" عِوض البادئة "$2a$".
  • CRYPT_SHA256: يُحدد نوع هاش باستعمال خوارزمية ‎SHA-256 .تكون قيمة المعامل salt سلسلة نصية مكونةً من 16 محرفًا تسبقها القيمة ‎$5$. إذا ابتدأت قيمة المعامل salt بالقيمة  'rounds=<N>$‎' فإن العدد ‎N يُمَثِل عدد تكرارات الهاش، حيث يلعب نفس دور المعامل ‎cost لدى خوارزمية Blowfish. العدد الافتراضي المُحدد لعدد التكرارات هو 5000 مع حد أدنى بقيمة 1000 تكرار وحد أقصى بقيمة 9999.999.999 تكرار. إذا كانت قيمة المعامل‎N ‎ خارج هذا المجال فستُحَول إلى أقرب قيمة تتواجد داخل المجال.
  • CRYPT_SHA512: يُحدد نوع هاش باستعمال خوارزمية SHA512‎. تكون قيمة المعامل salt سلسلةً نصيةً مكونة من 16 محرفًا تسبقها القيمة ‎$6$. إذا ابتدأت قيمة المعامل salt بالقيمة 'rounds=<N>$‎' فإن العدد ‎N يُمَثِل عدد تكرارات الهاش، إذ يلعب نفس دور المعامل ‎ cost لدى خوارزمية Blowfish. العدد الافتراضي المُحدد لعدد التكرارات هو 5000 مع حد أدنى بقيمة 1000 تكرار وحد أقصى بقيمة 9999.999.999 تكرار. إذا كانت قيمة المعامل‎N ‎ خارج هذا المجال تُحَول إلى أقرب قيمة تتواجد داخل المجال.

ملاحظة: تحتوي لغة ‎PHP بدءًا من النسخة 5.3.0 على تطبيق الخوارزميات خاص بها، إذ تُستعمَل في حال عدم توافر هذه الخوارزميات في نظام التشغيل.

المعاملات

str

السلسلة النصية التي سيتم عمل الهاش لها.

تنبيه: ستُقطَّع السلسلة النصية ‎‎str عند استعمال خوارزمية ‎CRYPT_BLOWFISH إلى قطع بأقصى طول يساوي 72 محرفًا.

salt

سلسلة نصية اختيارية يعتمد نوع الهاش عليها. إذا لم تُضبَط قيمة المعامل ‎salt فسيكون سلوك الدالة ‎crypt()‎ معتمدًاعلى خوارزمية الهاش، مما يؤدي إلى نتائج غير متوقعة.

القيم المعادة

تعيد الدالة ‎‎crypt()‎ السلسلة النصية بعد تطبيق الهاش عليها أو سلسلة نصية بطول أقل من 13 محرف ومختلفة عن قيمة المعامل ‎‎‎‎‎salt في حال الفشل.

تحذير: يتعين استعمال دالة محصنة ضد الهجمات المؤقتة (timing attacks، التي تُحلِّل الزمن اللازم لتوليد الشيفرة لمعرفة السلسلة النصية الأصلية) لمقارنة مخرج الدالة ‎crypt()‎ مع قيمة هاش معروفة سابقًا عند التحقق من كلمات المرور.

تقدم نسخة 5.6 وما بعدها للغة ‎‎PHP الدالة ‎hash_equals()‎ لمقارنة مخرج الدالة ‎crypt()‎ مع قيمة هاش معروفة سابقًا.

سجل التغييرات

الإصدار الوصف
5.6.5 عند إعطاء قيمة الفشل ‎*0 للمعامل salt فستُعيد الدالة crypt()‎ القيمة ‎*1 لكي تماثل سلوك التطبيقات المختلفة للتشفير. قبل هذا الإصدار، ستُعيد لغة  PHP 5.6 خطأً هاش بخوارزمية DES.
5.6.0 تُظهِر الدالة crypt()‎ تحذيرًا أمنيًا E_NOTICE في حال غياب المعامل salt.
5.5.21 عند إعطاء قيمة الفشل ‎*0 للمعامل salt فستُعيد الدالة crypt()‎ القيمة ‎*1 لكي تماثل سلوك التطبيقات المختلفة للتشفير. قبل هذا الإصدار، ستُعيد لغة PHP 5.6 (والفروع السابقة) خطأً هاش بخوارزمية DES.
5.3.7 إضافة الوضعين $2x$ و $2y$ إلى خوارزمية Blowfish للتعامل مع هجمات البايت العلوي (high-bit).
5.3.2 إضافة الخوارزميتين SHA-256 و SHA-512 إلى تطبيق أولريش دريبر (Ulrich Drepper)
5.3.2 إصلاح سلوك خوارزمية Blowfish بخصوص التكرارات غير الصالحة لِتُعيد سلسلة النصوص تدُل على الفشل ("‎*0" أو  "‎*1") بدلًا من تطبيق خوارزمية DES.
5.3.0 بدءًا من هذه النسخة، امتلكت لغة PHP تطبيقاتها الخاصة بخوارزميات MD5 crypt و Standard DES و Extended DES و Blowfish.

أمثلة

المثال 1: مثال بسيط عن الدالة ‎‎crypt()‎

يتوجب إعطاء قيمة المعامل salt القيمة المعادة من الدالة crypt()‎ عند مقارنة كلمات المرور لتجنب المشاكل عند استعمال خوارزميات هاش مختلفة. كما ذكرنا سابقًا تستعمل دالة الهاش المبنية على معيار تشفير البيانات DES معامل salt يتكون من حرفين و تستعمل دالة الهاش المبنية على خوارزمية MD5 معامل salt من 12 محرفًا.

<?php
$hashed_password = crypt('mypassword');

if (hash_equals($hashed_password, crypt($user_input, $hashed_password))) {
  echo "Password verified!";
}
?>

المثال 2: مثال عن استعمال الدالة ‎crypt()‎ مع كلمات المرور

<?php
$password = 'mypassword';
$hash = crypt($password);
?>

المثال 3: مثال عن استعمال الدالة ‎crypt()‎ مع مختلف أنواع خوارزميات الهاش تعدّ قيم المعامل salt المستعملة أدناه مجرد أمثلة فقط، يجدر بك اختيار قيم مختلفة للمعامل salt.

<?php

if (CRYPT_STD_DES == 1) {
    echo 'Standard DES: ' . crypt('rasmuslerdorf', 'rl') . "\n";
}

if (CRYPT_EXT_DES == 1) {
    echo 'Extended DES: ' . crypt('rasmuslerdorf', '_J9..rasm') . "\n";
}

if (CRYPT_MD5 == 1) {
    echo 'MD5:          ' . crypt('rasmuslerdorf', '$1$rasmusle$') . "\n";
}

if (CRYPT_BLOWFISH == 1) {
    echo 'Blowfish:     ' . crypt('rasmuslerdorf', '$2a$07$usesomesillystringforsalt$') . "\n";
}

if (CRYPT_SHA256 == 1) {
    echo 'SHA-256:      ' . crypt('rasmuslerdorf', '$5$rounds=5000$usesomesillystringforsalt$') . "\n";
}

if (CRYPT_SHA512 == 1) {
    echo 'SHA-512:      ' . crypt('rasmuslerdorf', '$6$rounds=5000$usesomesillystringforsalt$') . "\n";
}
?>

سيُخرِج المثال السابق الناتج الآتي:

‎Standard DES:rl.3StKT.4T8M

Extended DES:_J9..rasmBYk8r9AiWNc

MD5:$1$rasmusle$rISCgZzpwk3UhDidwXvin0

Blowfish:$2a$07$usesomesillystringfore2uDLvp1Ii2e./U9C8sBjqp8I90dH6hi

SHA-256:$5$rounds=5000$usesomesillystri$KqJWpanXZHKq2BOB43TSaYhEWsQ1Lr5QNyPCDH/Tp.6

SHA-512:$6$rounds=5000$usesomesillystri$D4IrlXatmP7rx3P3InaxBeoomnAihCKRVQP22JZ6EY47Wc6BkroIuUUBOov1i.S5KPgErtP/EN5mcO.ChWQW21

ملاحظة: لا يوجد دالة تفك تشفير الدالة crypt()‎ لأنها دالة تشفير وحيدة الإتجاه.

انظر أيضًا:

  • hash_equals()‎: مقارنة سلاسل نصية مؤمنة ضد الهجمات الموقوتة (‎Timing attack).
  • password_hash()‎: إنتاج هاشات كلمات المرور.  
  • md5()‎: حساب هاش السلسلة النصية بإستعمال الخوارزمية md5.
  • صفحة الدليل man للدالة crypt في أنظمة يونكس.

مصادر