Abdulmohsen Blog

Programmer, Works @ Kuwait Civil Aviation

ACoders @ Twitter

الطريقة الصحيحة لتشفير الرمز السري بـ PHP

hdrلقد لاحظ الجميع في الآونة الأخيرة اختراق مواقع شركات كبيره مثل شبكة سوني الخاصة بي بجهاز PlayStation ، ومن يتابع مثل هذه الأخبار يري مدي تساهل الشركات مع بيانات العملاء، والخطأ الفادح بعدم تشفير بيانات العملاء او استخدام تشفير سهل مثل MD5, SHA1 ، هذه النوع من التشفير سهل جداً كسره فهو لم يصمم بالأساس لحماية الأرقام السرية، بعكس تشفير BCrypt و SCrypt لقد تم تصميم هذه الأنواع لكي تصعب عملية كسر التشفيرعن طريق الهاش باستخدام طرق مثل (BF, RTA, GBP).

كيف تستطيع حماية الرموز السرية في برمجيتك؟

اذا كنت تستخدم نسخه أحدث من PHP 5.3.7 قم باستخدام هذه البرمجية، أما اذا كنت تستخدم نسخه أقدم من 5.3.7 فقم باستخدام هذه البرمجية، ولكن أتمني منك تطوير النسخة التي تستخدمها الي PHP 5.6.x او اعلي و ذالك لآنه تم تصليح كثير من المشاكل و إضافة العديد من الميزات الجديدة، وعلماً بأنه نسخة PHP 5.3.x قد انتهى الدعم عنها ولن يتم تصليح اي مشاكل او ثغرات بها، ولمعرفة المزيد عن اي نسخه من PHP قم بالدخول إلى هذه الرابط.

معلومات عن password_compat

هذا البرمجه تمت كتبتها عن طريق المبرمج Anthony Ferrara، و هو احد مطورين فريق لغة PHP، و لقد قام بكتابة هذا البرمجية لكي تكون متوافقه تماماً مع الدلالات الخاصة بتشفير الأرقام السرية الموجودة في نسخه PHP 5.5 وأعلى و تستطيع معرفة المزيد على هذه الرابط.

تنزل ملف password_compat

اذا كنت تستخدم اداة Composer ، فهذا السكربت متوفر للتنزيل بضغطة زر واحدة، من هذه الموقع الخاص بالأداة سأقوم بشرح الاداة بالمستقبل بأذن الله، و تستطيع أيضاً نسخ الكود من الرابط الذي قمت بذكرة في الأعلى وإنشاء ملف خاص به.

طريقة الإستخدام

اذا قمت بتنزيل السكربت عن طريق Composer فقم بتجاهل هذه الخطوة، قم بتسمية الكود الذي قمت بنسخه باسم password_compat.php ، و لكي تستطيع استخدام الدلالات قم بوضع هذه الكود في المكان الذي تريد تشفير الارقام السرية به او التحقق من الرقم السري.

include_once 'password_compat.php';

تشفير رقم سري

$hash = password_hash( $password, PASSWORD_BCRYPT, [ 'cost' => 10 ] ); 

قم بتغير مُتغير $password للرقم السري، وتستطيع تغير متغير cost بين 4 الي 31، وذالك لزيادة التكلفة على المعالج CPU، كُل ما زاد الرقم اصبحت مطابقة الرقم السري أبطا، انا افضل رقم 10 للمواقع العادية، و للمواقع ذات الطابع الخاص بين 20 الى 31.

كيف تستطيع معرفة أن الرقم السري المُدخل مطابق للهاش؟

الطريقة سهله جداً، أولا طريقة القديمة لمعرفة الرقم كانت بسابق كتالي

$password = md5( $password );

$sql = "SELECT 
                * 
            FROM 
                users 
            WHERE 
                password = '{$password}' 
            AND 
                username = '{$username}' 
            LIMIT 
                1
";

$result = mysqli_query( $link, $sql );

if ( mysqli_num_rows( $result ) < 1)
{
    die("البيانات غير صحيحة");
}

echo "اهلا وسهلا";

انا لم أقم بكتابة الكود كامل وذالك لمنع احد من نسخ الكود بالأعلى واستخدامه لأنه غير آمن، تشاهد بانه سيتم أولا تشفير الرقم السري و من ثم البحث عن العضو في قاعدة البيانات، و لكن بسبب استخدام تشفير BCrypt لن تستطيع البحث لأنه في كل مره تقوم باستخدام دلالة password_hash سيتم ارجاع بيانات مختلفه حتى لو تم استخدام نفس الرقم السري، و ذلك لآنه يتم إضافة ترميز عشوائي Salt للرقم السري مُختلف عن السابق، فأذأ ماهي الطريقة الصحيحة للتحقق من الرقم السري؟ الطريقة كتالي

$sql = "SELECT 
                * 
            FROM 
                users 
            WHERE 
                username =  '{$username}' 
            LIMIT 
                 1
";

$result = mysqli_query($link, $sql);
if ( mysqli_num_rows($result) < 1)
{
   die("البيانات غير صحيحة");
}

$row = mysqli_fetch_row($result);
if ( !password_verify( $_POST['password'], $row['user_password'] ) )
{
        die("البيانات غير صحيحة")
}
echo sprintf("اهلا وسهلا بك %s", $row['username']);

تغير التشفير

بين الفترة و الأخرى تحتاج الى تغير التشفير المُستخدم او التكلفه فتستطيع استخدام الكود التالي للتعرف بأنه الهاش يستخدم الشتفير القديم او التكلفة القديمة، و تحديثه بالخيارات الجديدة.


//-- بعد التأكد بانه الرقم السري صحيح في صفحة الدخول، قم بإستخدام هذه الكود
$options = array('cost' => 12); // -- تغير مدى التكلفه على المعالج

$algorithm = PASSWORD_SCRYPT; // -- تغير نوع التشفير

if ( password_needs_rehash($hash, $algorithm, $options) )
{
    $hash = password_hash($password, $algorithm, $options);

    /** تحديث قاعدة البيانات بالهاش الجديد */
    $sql = "update users set password = '{$hash}' where id = 1";
}

طريقة استخدام phpass

بعد تحميل الملف المضغوط، قم بفك الضغط ورفع ملف passwordHash.php لموقعك

ومن ثم قم بنسخ الكود التالي للصفحة التي تريد أن تقوم باستخدام الرقم السري بها، مثل (صفحة التسجيل، الدخول) و اي صحفة قد تطلب فيها أعادة إدخال الرقم السري.

include_once 'passwordHash.php';

طريقة التشفير الرقم السري باستخدام phpass

//-- مدي التكلفة على المعالج
$cost = 10;

$phpass = new PasswordHash( $cost, false );

$hash = $phpass->HashPassword( $_POST['password'] );

if ( strlen($hash) < 20 )
{
    die('Failed to hash new password');
}

طريقة التأكيد بأن الرقم السري مُطابق للهاش

بنفس الطريقة المذكورة في الأعلى تقوم بجلب البيانات أولا من قاعدة البيانات ومن ثم استخدام الكود التالي

if ( !$phpass->checkPassword( $_POST['password'], $row['user_password'] ) )
{
    die('البيانات غير صحيحة');
}
echo sprintf("اهلا وسهلا بك %s", $row['username']);

للأسف برمجية phpass لا توفر طريقة لكي تعرف ان الهاش يستخدم تشفير قديم مثل ماهو مستخدم في password_compat ، تستطيع قراءة المزيد حول برمجية phpass على هذه الرابط.

التعليقات