سؤال

يُقال حاليًا أن MD5 غير آمن جزئيًا.مع أخذ ذلك في الاعتبار، أود أن أعرف الآلية التي يجب استخدامها لحماية كلمة المرور.

هذا السؤال، هل "التجزئة المزدوجة" هي كلمة مرور أقل أمانًا من مجرد تجزئتها مرة واحدة؟ يشير إلى أن التجزئة عدة مرات قد تكون فكرة جيدة، في حين أن كيفية تنفيذ حماية كلمة المرور للملفات الفردية؟ يقترح استخدام الملح.

أنا أستخدم PHP.أريد نظام تشفير كلمة المرور آمن وسريع.قد يكون تجزئة كلمة المرور مليون مرة أكثر أمانًا، ولكنه أبطأ أيضًا.كيفية تحقيق توازن جيد بين السرعة والسلامة؟كما أفضّل أن تحتوي النتيجة على عدد ثابت من الأحرف.

  1. يجب أن تكون آلية التجزئة متاحة في PHP
  2. يجب أن تكون آمنة
  3. يمكنه استخدام الملح (في هذه الحالة، هل جميع الأملاح جيدة بنفس القدر؟هل هناك أي طريقة لتوليد أملاح جيدة؟)

أيضًا، هل يجب أن أقوم بتخزين حقلين في قاعدة البيانات (أحدهما يستخدم MD5 والآخر يستخدم SHA، على سبيل المثال)؟هل سيجعلها أكثر أمانًا أم أقل أمانًا؟

في حال لم أكن واضحًا بما فيه الكفاية، أريد أن أعرف وظيفة (وظائف) التجزئة التي يجب استخدامها وكيفية اختيار ملح جيد للحصول على آلية آمنة وسريعة لحماية كلمة المرور.

الأسئلة ذات الصلة التي لا تغطي سؤالي تمامًا:

ما الفرق بين SHA وMD5 في PHP
تشفير كلمة المرور البسيطة
طرق آمنة لتخزين المفاتيح وكلمات المرور لـ asp.net
كيف يمكنك تنفيذ كلمات المرور المملحة في Tomcat 5.5

هل كانت مفيدة؟

المحلول

تنصل:تمت كتابة هذه الإجابة في عام 2008.

ومنذ ذلك الحين، أعطتنا PHP password_hash و password_verify ومنذ تقديمها، أصبحت طريقة تجزئة كلمة المرور والتحقق منها موصى بها.

نظرية الإجابة لا تزال جيدة للقراءة بالرغم من ذلك.

ليرة تركية؛ د

لا تفعل ذلك

  • لا تحد من الأحرف التي يمكن للمستخدمين إدخالها لكلمات المرور.الأغبياء فقط هم من يفعلون هذا
  • لا تحد من طول كلمة المرور.إذا كان المستخدمون لديك يريدون جملة تحتوي على supercalifragilisticexpialidocious، فلا تمنعهم من استخدامها.
  • لا تقم مطلقًا بتخزين كلمة مرور المستخدم الخاصة بك في نص عادي.
  • لا ترسل أبدًا كلمة مرور إلى المستخدم الخاص بك إلا إذا فقدوا أمتعتهم وأرسلت واحدا مؤقتا.
  • لا تقم مطلقًا بتسجيل كلمات المرور بأي شكل من الأشكال.
  • لا تقم مطلقًا بتجزئة كلمات المرور باستخدام SHA1 أو MD5 أو حتى SHA256! المفرقعات الحديثة يمكن أن تتجاوز 60 و180 مليار تجزئة في الثانية (على التوالي).
  • لا تخلط bcrypt ومع خام إخراج التجزئة (), إما أن تستخدم الإخراج السداسي أو base64_encode.(ينطبق هذا على أي مدخلات قد تكون محتالة \0 فيه، الأمر الذي يمكن أن يضعف الأمن بشكل خطير.)

دوس

  • استخدم scrypt عندما تستطيع؛bcrypt إذا لم تتمكن من ذلك.
  • استخدم PBKDF2 إذا لم تتمكن من استخدام bcrypt أو scrypt، مع تجزئة SHA2.
  • إعادة تعيين كلمات المرور للجميع عندما يتم اختراق قاعدة البيانات.
  • يجب تنفيذ حد أدنى معقول لطول يتراوح من 8 إلى 10 أحرف، بالإضافة إلى المطالبة بحرف كبير واحد على الأقل وحرف صغير واحد ورقم ورمز.سيؤدي ذلك إلى تحسين إنتروبيا كلمة المرور، مما يزيد من صعوبة اختراقها.(راجع قسم "ما الذي يجعل كلمة المرور جيدة؟" للاطلاع على بعض المناقشات.)

لماذا تجزئة كلمات المرور على أي حال؟

الهدف من وراء تجزئة كلمات المرور بسيط:منع الوصول الضار إلى حسابات المستخدمين عن طريق اختراق قاعدة البيانات.لذا فإن الهدف من تجزئة كلمة المرور هو ردع المتسللين أو المتسللين من خلال تكلفتهم الكثير من الوقت أو المال لحساب كلمات المرور ذات النص العادي.والوقت/التكلفة هما أفضل العوائق في ترسانتك.

السبب الآخر الذي يجعلك تريد تجزئة جيدة وقوية على حسابات المستخدمين هو منحك الوقت الكافي لتغيير جميع كلمات المرور في النظام.إذا تم اختراق قاعدة البيانات الخاصة بك، فستحتاج إلى وقت كافٍ للقيام بذلك الأقل قفل النظام، إن لم يكن تغيير كل كلمة المرور في قاعدة البيانات.

جيريميا غروسمان، الرئيس التنفيذي للتكنولوجيا في شركة Whitehat Security، جاء في مدونته بعد استعادة كلمة المرور مؤخرًا والتي تطلبت كسرًا شديدًا لحماية كلمة المرور الخاصة به:

ومن المثير للاهتمام، أثناء عيشي هذا الكابوس، تعلمت الكثير مما لم أكن أعرفه عن اختراق كلمات المرور وتخزينها وتعقيدها. لقد أدركت السبب الذي يجعل تخزين كلمة المرور أكثر أهمية من تعقيد كلمة المرور.إذا كنت لا تعرف كيفية تخزين كلمة المرور الخاصة بك، فكل ما يمكنك الاعتماد عليه حقًا هو التعقيد. قد تكون هذه معلومة شائعة لمحترفي كلمات المرور والعملات المشفرة، ولكن بالنسبة لخبير أمن المعلومات أو أمن الويب العادي، فأنا أشك في ذلك بشدة.

(التأكيد على الألغام.)

ما الذي يجعل أ جيد كلمة المرور على أي حال؟

إنتروبيا.(لا يعني ذلك أنني أؤيد وجهة نظر راندال بالكامل).

باختصار، الإنتروبيا هي مقدار الاختلاف الموجود داخل كلمة المرور.عندما تكون كلمة المرور عبارة عن أحرف رومانية صغيرة فقط، فهذا يعني 26 حرفًا فقط.هذا ليس الكثير من الاختلاف.كلمات المرور الأبجدية الرقمية أفضل، حيث تتكون من 36 حرفًا.لكن السماح بالأحرف الكبيرة والصغيرة، مع الرموز، يصل إلى 96 حرفًا تقريبًا.هذا أفضل بكثير من مجرد رسائل.إحدى المشكلات هي أنه لكي نجعل كلمات المرور الخاصة بنا سهلة التذكر، فإننا نقوم بإدخال أنماط، مما يقلل من الإنتروبيا.أُووبس!

الإنتروبيا كلمة المرور هي تقريبي بسهولة.يؤدي استخدام النطاق الكامل لأحرف ascii (حوالي 96 حرفًا قابلاً للكتابة) إلى الحصول على إنتروبيا تبلغ 6.6 لكل حرف، والتي عند 8 أحرف لكلمة المرور لا تزال منخفضة جدًا (52.679 بت من الإنتروبيا) بالنسبة للأمان المستقبلي.لكن الخبر السار هو:كلمات المرور الأطول، وكلمات المرور التي تحتوي على أحرف Unicode، تزيد بالفعل من إنتروبيا كلمة المرور وتجعل من الصعب اختراقها.

هناك مناقشة أطول حول إنتروبيا كلمة المرور على تشفير StackExchange موقع.سيؤدي البحث الجيد على Google أيضًا إلى ظهور الكثير من النتائج.

تحدثت في التعليقات معpopnoodles الذي أشار إلى ذلك إنفاذ يمكن لسياسة كلمة المرور بطول X مع عدد X من الأحرف والأرقام والرموز وما إلى ذلك، أن تقلل في الواقع الإنتروبيا عن طريق جعل نظام كلمة المرور أكثر قابلية للتنبؤ به.أنا أوافق.Randomess، العشوائي حقًا قدر الإمكان، هو دائمًا الحل الأكثر أمانًا ولكن الأقل تذكرًا.

بقدر ما أستطيع أن أقول، فإن أفضل كلمة مرور في العالم هي Catch-22.إما أنه لا يمكن تذكره، أو يمكن التنبؤ به جدًا، أو قصير جدًا، أو يحتوي على عدد كبير جدًا من أحرف Unicode (يصعب كتابتها على جهاز يعمل بنظام Windows/Mobile)، أو طويل جدًا، وما إلى ذلك.لا توجد كلمة مرور جيدة بما يكفي لتحقيق أغراضنا، لذا يجب علينا حمايتهم كما لو كانوا في فورت نوكس.

أفضل الممارسات

بكريبت و scrypt هي أفضل الممارسات الحالية. سكريبت سيكون أفضل من bcrypt مع مرور الوقت، لكنه لم يتم اعتماده كمعيار بواسطة Linux/Unix أو بواسطة خوادم الويب، ولم يتم نشر مراجعات متعمقة للخوارزمية الخاصة به حتى الآن.لكن لا يزال مستقبل الخوارزمية يبدو واعدًا.إذا كنت تعمل مع روبي، فهناك جوهرة سكريبت سيساعدك ذلك، وأصبح لدى Node.js الآن خاصيته scrypt طَرد.يمكنك استخدام Scrypt في PHP إما عبر ملف سكريبت التمديد أو ليبسوديوم التمديد (كلاهما متوفر في PECL).

أقترح بشدة قراءة الوثائق الخاصة بـ وظيفة التشفير إذا كنت تريد فهم كيفية استخدام bcrypt، أو العثور على ملف جيد غلاف أو استخدام شيء من هذا القبيل PHPASS لتنفيذ المزيد من الإرث.أوصي بما لا يقل عن 12 جولة من bcrypt، إن لم يكن من 15 إلى 18.

لقد غيرت رأيي بشأن استخدام bcrypt عندما علمت أن bcrypt يستخدم فقط جدول مفاتيح السمكة المنتفخة، مع آلية التكلفة المتغيرة.يتيح لك هذا الأخير زيادة تكلفة فرض كلمة مرور عن طريق زيادة جدول المفاتيح الباهظ الثمن بالفعل الخاص بالسمكة المنتفخة.

ممارسات متوسطة

أكاد لا أستطيع تخيل هذا الوضع بعد الآن. PHPASS يدعم PHP 3.0.18 إلى 5.3، لذلك يمكن استخدامه في كل عملية تثبيت يمكن تخيلها تقريبًا - ويجب استخدامه إذا لم تقم بذلك أعرف على وجه اليقين أن بيئتك تدعم bcrypt.

لكن لنفترض أنه لا يمكنك استخدام bcrypt أو PHPASS على الإطلاق.ماذا بعد؟

حاول تنفيذ PDKBF2 مع ال الحد الأقصى لعدد الجولات التي يمكن أن تتحملها بيئتك/تطبيقك/تصور المستخدم.أقل رقم أوصي به هو 2500 طلقة.تأكد أيضًا من استخدامه hash_hmac() إذا كان متاحًا لجعل إعادة إنتاج العملية أكثر صعوبة.

الممارسات المستقبلية

يأتي في PHP 5.5 هو مكتبة حماية كلمة المرور الكاملة هذا يزيل أي متاعب العمل مع bcrypt.في حين أن معظمنا عالق في PHP 5.2 و5.3 في معظم البيئات الشائعة، وخاصة المضيفين المشتركين، فقد أنشأ @ircmaxell طبقة التوافق لواجهة برمجة التطبيقات (API) القادمة المتوافقة مع PHP 5.3.7.

خلاصة التشفير وإخلاء المسؤولية

القوة الحسابية المطلوبة في الواقع كسر كلمة المرور المجزأة غير موجودة.الطريقة الوحيدة لأجهزة الكمبيوتر "لاختراق" كلمة المرور هي إعادة إنشائها ومحاكاة خوارزمية التجزئة المستخدمة لتأمينها.ترتبط سرعة التجزئة خطيًا بقدرتها على القوة الغاشمة.والأسوأ من ذلك هو أن معظم خوارزميات التجزئة يمكن موازنتها بسهولة لأداء أسرع.هذا هو سبب أهمية المخططات المكلفة مثل bcrypt وscrypt.

لا يمكنك توقع جميع التهديدات أو سبل الهجوم، ولذلك يجب عليك بذل قصارى جهدك لحماية المستخدمين صريح.إذا لم تقم بذلك، فقد تفوتك حقيقة أنك تعرضت للهجوم حتى فوات الأوان... وأنت مسؤول.لتجنب هذا الموقف، تصرف بجنون العظمة في البداية.قم بمهاجمة برنامجك الخاص (داخليًا) ومحاولة سرقة بيانات اعتماد المستخدم أو تعديل حسابات المستخدمين الآخرين أو الوصول إلى بياناتهم.إذا لم تختبر أمان نظامك، فلا يمكنك إلقاء اللوم على أي شخص غير نفسك.

أخيرا:أنا لست متخصصًا في التشفير.كل ما قلته هو رأيي، ولكن أعتقد أنه مبني على الفطرة السليمة ...والكثير من القراءة.تذكر، كن مذعورًا قدر الإمكان، واجعل من الصعب التطفل على الأشياء قدر الإمكان، وبعد ذلك، إذا كنت لا تزال قلقًا، فاتصل بمتسلل ذو قبعة بيضاء أو متخصص في التشفير لمعرفة ما يقولونه عن الكود/النظام الخاص بك.

نصائح أخرى

إجابة أقصر وأكثر أمانًا - لا تكتب آلية كلمة المرور الخاصة بك على الإطلاق, ، استخدم آلية مجربة ومختبرة.

  • PHP 5.5 أو أعلى: password_hash () هي نوعية جيدة وجزء من PHP Core.
  • إصدارات PHP الأقدم: OpenWall's phass المكتبة أفضل بكثير من معظم التعليمات البرمجية المخصصة - المستخدمة في WordPress ، Drupal ، إلخ.

معظم المبرمجين ليس لديهم خبرة في كتابة التعليمات البرمجية المتعلقة بالتشفير بأمان دون تقديم نقاط الضعف.

اختبار ذاتي سريع: ما هي تمديد كلمة المرور وكم عدد التكرارات التي يجب أن تستخدمها؟ إذا كنت لا تعرف الإجابة ، فيجب عليك استخدامها password_hash(), ، نظرًا لأن تمديد كلمة المرور أصبح الآن ميزة مهمة لآليات كلمة المرور بسبب وحدات المعالجة المركزية الأسرع بكثير واستخدامها وحدات معالجة الرسومات و FPGAs لكسر كلمات المرور بمعدلات مليارات التخمينات في الثانية (مع وحدات معالجة الرسومات).

على سبيل المثال ، يمكنك كسر جميع كلمات مرور Windows المكونة من 8 أحرف في 6 ساعات باستخدام 25 وحدات معالجة الرسومات المثبتة في 5 أجهزة كمبيوتر سطح المكتب. هذا هو التعداد والتحقق كل كلمة مرور Windows 8 أحرف, ، بما في ذلك الشخصيات الخاصة ، وليس هجوم القاموس. كان ذلك في عام 2012 ، اعتبارًا من عام 2018 ، يمكنك استخدام عدد أقل من وحدات معالجة الرسومات ، أو تصدع أسرع مع 25 وحدات معالجة الرسومات.

هناك أيضًا العديد من هجمات Table Table على كلمات مرور Windows التي تعمل على وحدات المعالجة المركزية العادية وسريعة للغاية. كل هذا بسبب ويندوز ساكن لا الملح أو تمتد كلمات المرور الخاصة بها ، حتى في Windows 10 - لا ترتكب نفس الخطأ كما فعلت Microsoft!

أنظر أيضا:

  • إجابة ممتازة مع المزيد حول لماذا password_hash() أو phpass هي أفضل طريقة للذهاب.
  • مقالة مدونة جيدة إعطاء "عوامل العمل" الموصى بها (عدد التكرارات) للخوارزميات الرئيسية بما في ذلك BCrypt و Scrypt و PBKDF2.

لن أتخّن تجزئة كلمة المرور بطريقتين مختلفتين ، لأن النظام بعد ذلك على الأقل ضعيف مثل الأضعف في خوارزميات التجزئة المستخدمة.

اعتبارًا من PHP 5.5 ، لدى PHP وظائف بسيطة وآمنة لجامع كلمات المرور والتحقق من كلمات المرور ، password_hash () و password_verify ()

$password = 'anna';
$hash = password_hash($password, PASSWORD_DEFAULT);
$expensiveHash = password_hash($password, PASSWORD_DEFAULT, array('cost' => 20));

password_verify('anna', $hash); //Returns true
password_verify('anna', $expensiveHash); //Also returns true
password_verify('elsa', $hash); //Returns false

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

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

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

لاحظ أنه على الرغم من أن خوارزمية التجزئة الافتراضية قد تتغير ، فإن التجزئة القديمة ستستمر في التحقق بشكل جيد لأن الخوارزمية المستخدمة يتم تخزينها في التجزئة و password_verify() تلتقط عليه.

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

يتوفر المزيد من التفسير في- http://www.pivotalsecurity.com/blog/password-hashing-salt-hould-it-be-random/

في الآونة الأخيرة ، أجريت مناقشة ما إذا كانت كلمة المرور المملحة مع أجزاء عشوائية أكثر أمانًا من تلك المملحة بأملاح قابلة للتخمين أو معروفة. دعونا نرى: إذا تم اختراق كلمة مرور تخزين النظام بالإضافة إلى النظام الذي يخزن الملح العشوائي ، فسيكون للمهاجم الوصول إلى التجزئة والملح ، لذلك سواء كان الملح عشوائيًا أم لا ، لا يهم. يمكن للمهاجم توليد طاولات قوس قزح محسوبة مسبقًا لكسر التجزئة. هنا يأتي الجزء المثير للاهتمام- ليس من التافهة إنشاء جداول محسوبة مسبقًا. دعونا نأخذ مثال على نموذج أمان WPA. لا يتم إرسال كلمة مرور WPA الخاصة بك أبدًا إلى نقطة الوصول اللاسلكية. بدلاً من ذلك ، يتم تجزئة مع SSID (اسم الشبكة- مثل Linksys ، DLINK ETC). شرح جيد جدًا لكيفية عمل هذا هنا. لاسترداد كلمة المرور من التجزئة ، ستحتاج إلى معرفة كلمة المرور وكذلك الملح (اسم الشبكة). لدى Church of WiFi بالفعل جداول التجزئة التي تم حسابها مسبقًا والتي لديها أفضل 1000 SSIDs وحوالي مليون كلمة مرور. الحجم من جميع الجداول حوالي 40 جيجابايت. كما يمكنك القراءة على موقعه ، استخدم شخص ما 15 صفيف FGPA لمدة 3 أيام لإنشاء هذه الجداول. على افتراض أن الضحية تستخدم SSID باسم "A387CSF3 ″ وكلمة المرور كـ" 123456 ″ ، هل سيتم تكسيرها بواسطة تلك الجداول؟ رقم! .. لا تستطيع. حتى إذا كانت كلمة المرور ضعيفة ، فإن الجداول لا تحتوي على تجزئة لـ SSID A387CSF3. هذا هو جمال وجود ملح عشوائي. سوف يردع المفرقعات الذين يزدهرون على الجداول المحسوبة مسبقًا. هل يمكن أن يوقف المتسلل المصمم؟ على الاغلب لا. لكن استخدام الأملاح العشوائية يوفر طبقة إضافية من الدفاع. أثناء وجودنا في هذا الموضوع ، دعونا نناقش ميزة إضافية لتخزين الأملاح العشوائية على نظام منفصل. السيناريو رقم 1: يتم تخزين تجزئة كلمة المرور على النظام X ويتم تخزين قيم الملح المستخدمة في النظام Y. يتم تخزين التجزئة على النظام Y. هذه قيم الملح عشوائي. في حالة SAGE ، تم اختراق System X ، كما يمكنك أن تخمن ، هناك ميزة كبيرة في استخدام الملح العشوائي على نظام منفصل (السيناريو رقم 2). سيحتاج المهاجم إلى تخمين قيم الإضافة لتكون قادرة على كسر التجزئة. إذا تم استخدام ملح 32 بت ، 2^32 = 4،294،967،296 (حوالي 4.2 مليار) ، يمكن أن تكون هناك حاجة إلى كل كلمة مرور.

أريد فقط أن أشير إلى أن PHP 5.5 يتضمن أ كلمة المرور hashing API الذي يوفر غلاف حول crypt(). تعمل واجهة برمجة التطبيقات هذه على تبسيط مهمة التجزئة والتحقق من تجزئة كلمة المرور وإعادة صياغتها. أصدر المؤلف أيضًا أ حزمة التوافق (في شكل ملف كلمة مرور واحد require للاستخدام) ، لأولئك الذين يستخدمون PHP 5.3.7 وبعد ذلك ويريدون استخدام هذا الآن.

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

يعرض واجهة برمجة التطبيقات أربع وظائف:

  • password_get_info() - إرجاع معلومات حول التجزئة المعطاة
  • password_hash() - يخلق تجزئة كلمة المرور
  • password_needs_rehash() - يتحقق مما إذا كان التجزئة المعطاة يطابق الخيارات المعطاة. مفيد للتحقق مما إذا كان التجزئة يتوافق مع مخططك/التكلفة الحالية مما يتيح لك إعادة صياغة إذا لزم الأمر
  • password_verify() - يتحقق من أن كلمة المرور تتطابق مع التجزئة

في الوقت الحالي ، تقبل هذه الوظائف ثوابت Password_BCrypt و Password_Default ، وهي مرادف في الوقت الحالي ، والفرق هو أن كلمة المرور _default "قد تتغير في إصدارات PHP الأحدث عند دعم خوارزميات التجزئة الأحدث والأقوى." باستخدام password_default و password_needs_rehash () على تسجيل الدخول (وإعادة صياغة إذا لزم الأمر) يجب أن يضمن أن تجزئةك مرنة بشكل معقول للهجمات القوية مع القليل من العمل من أجلك.

تحرير: لقد أدركت للتو أن هذا مذكور لفترة وجيزة في إجابة روبرت ك. سأترك هذه الإجابة هنا لأنني أعتقد أنها توفر المزيد من المعلومات حول كيفية عملها وسهولة الاستخدام التي توفرها لأولئك الذين لا يعرفون الأمن.

أنا استخدم phass وهي فئة PHP واحدة بسيطة واحدة يمكن تنفيذها بسهولة شديدة في كل مشروع PHP تقريبًا. أنظر أيضا ح.

بشكل افتراضي ، استخدمت أقوى تشفير متاح يتم تنفيذه في Phass ، وهو bcrypt ويعود إلى تشفيرات أخرى وصولاً إلى MD5 لتوفير توافق متخلف لأطر مثل WordPress.

يمكن تخزين التجزئة التي تم إرجاعها في قاعدة البيانات كما هي. استخدام العينة لتوليد التجزئة هو:

$t_hasher = new PasswordHash(8, FALSE);
$hash = $t_hasher->HashPassword($password);

للتحقق من كلمة المرور ، يمكن للمرء استخدام:

$t_hasher = new PasswordHash(8, FALSE);
$check = $t_hasher->CheckPassword($password, $hash);

أشياء للذكرى

لقد قيل الكثير عن تشفير كلمة المرور لـ PHP ، ومعظمها نصيحة جيدة للغاية ، ولكن قبل أن تبدأ عملية استخدام PHP لتشفير كلمة المرور ، تأكد من أن لديك ما يلي ما يلفت التنفيذ أو جاهز للتنفيذ.

الخادم

الموانئ

بغض النظر عن مدى جودة التشفير الخاص بك ، إذا لم تقم بتأمين الخادم الذي يعمل بشكل صحيح على تشغيل PHP و DB ، فكل جهودك لا قيمة لها. تعمل معظم الخوادم نسبيًا بنفس الطريقة ، لديها منافذ مخصصة للسماح لك بالوصول إليها عن بُعد إما من خلال FTP أو Shell. تأكد من تغيير المنفذ الافتراضي الذي تنشط فيه الاتصال عن بُعد. من خلال عدم القيام بذلك ، جعلت المهاجم يقوم بخطوة واحدة أقل في الوصول إلى نظامك.

اسم االمستخدم

على كل ما هو جيد في العالم ، لا تستخدم مسؤول اسم المستخدم أو الجذر أو شيء مشابه. وأيضًا إذا كنت تعمل على نظام UNIX لا تجعل تسجيل الدخول إلى حساب الجذر متاحًا ، فيجب أن يكون دائمًا sudo فقط.

كلمه السر

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

قاعدة البيانات

الخادم

من الناحية المثالية ، تريد DB وتطبيقك على خوادم منفصلة. هذا ليس ممكنًا دائمًا بسبب التكلفة ، لكنه يسمح ببعض الأمان حيث سيتعين على المهاجم أن يمر بخطوتين للوصول إلى النظام بالكامل.

المستعمل

لديك دائمًا طلبك حساب خاص به للوصول إلى DB ، ويمنحه فقط الامتيازات التي ستحتاجها.

ثم اطلب من حساب مستخدم منفصل لك أنه لم يتم تخزينه في أي مكان على الخادم ، ولا حتى في التطبيق.

كما هو الحال دائمًا لا تجعل هذا الجذر أو شيء مشابه.

كلمه السر

اتبع نفس الإرشادات كما هو الحال مع جميع كلمات المرور الجيدة. لا تعيد استخدام كلمة المرور نفسها على أي خادم أو حسابات ديسيبل على نفس النظام.

بي أتش بي

كلمه السر

لا تقم مطلقًا بتخزين كلمة مرور في ديسيبل ، بدلاً من ذلك ، قم بتخزين التجزئة والملح الفريد ، وسأشرح السبب في وقت لاحق.

التجزئة

طريقة واحدة تجزئة !!!!!!! ، لا تجزأ كلمة مرور بطريقة يمكن عكسها ، يجب أن تكون التجزئة في اتجاه واحد ، مما يعني أنك لا تعكسها ومقارنتها بكلمة المرور ، وبدلاً من ذلك ، يمكنك تجزئة كلمة المرور التي تم إدخالها بنفس الطريقة ومقارنة التجزئة. هذا يعني أنه حتى لو تمكن المهاجم من الوصول إلى ديسيبل ، فلا يعرف ما هي كلمة المرور الفعلية ، فقط تجزئةها الناتجة. مما يعني المزيد من الأمان للمستخدمين في أسوأ سيناريو ممكن.

هناك الكثير من وظائف التجزئة الجيدة (password_hash, hash, ، إلخ ...) ولكن تحتاج إلى اختيار خوارزمية جيدة ليكون التجزئة فعالة. (Bcrypt وتلك مماثلة لها خوارزميات لائقة.)

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

أحد أكثر الأخطاء شيوعًا في التجزئة هو أن التجزئة ليست فريدة من نوعها للمستخدمين. هذا أساسا لأن الأملاح لا يتم توليدها بشكل فريد.

التمليح

يجب دائمًا أن تكون كلمات المرور مملحة قبل الالستزول. يضيف Salting سلسلة عشوائية إلى كلمة المرور حتى لا تظهر كلمات المرور المماثلة كما هي في DB. ومع ذلك ، إذا لم يكن الملح فريدًا لكل مستخدم (أي: يمكنك استخدام الملح المشفر الصلب) مما جعلت الملح لا قيمة له. لأنه بمجرد أن يكتشف المهاجم ملح كلمة مرور واحدة ، يكون لديه الملح لهم جميعًا.

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

المستخدمون إنشاء كلمات المرور

إذا قام المستخدم بإنشاء كلمة مرور من خلال الواجهة الأمامية ، فهذا يعني أنه يجب إرسالها إلى الخادم. هذا يفتح مشكلة أمان لأن هذا يعني أن كلمة المرور غير المشفرة يتم إرسالها إلى الخادم وإذا كان المهاجم قادرًا على الاستماع والوصول إلى أن جميع أمانك في PHP لا قيمة له. قم دائمًا بنقل البيانات بشكل آمن ، ويتم ذلك من خلال SSL ، ولكن التعب حتى SSL لا تشوبه شائبة (عيب Openssl القلبي هو مثال على ذلك).

اجعل المستخدم أيضًا يقوم بإنشاء كلمة مرور آمنة ، إنها بسيطة ويجب القيام بها دائمًا ، سيكون المستخدم ممتنًا لها في النهاية.

أخيرًا ، بغض النظر عن التدابير الأمنية التي تتخذها ، فهي آمنة بنسبة 100 ٪ ، فكلما أصبحت التكنولوجيا الأكثر تقدماً للحماية أكثر تقدمًا ، أصبحت الهجمات. ولكن اتباع هذه الخطوات سيجعل موقعك أكثر أمانًا وأقل مرغوبًا فيه للمهاجمين لتلاحقهم.

فيما يلي فئة PHP التي تخلق تجزئة وملحًا لكلمة مرور بسهولة

http://git.io/msjqpw

يقول Google إن SHA256 متاح لـ PHP.

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

لقد وجدت موضوعًا مثاليًا في هذا الأمر هنا: https://crackstation.net/hashing-security.htm, ، أردت أن تستفيد منه ، إليك رمز المصدر أيضًا الذي يوفر الوقاية من الهجوم القائم على الوقت أيضًا.

<?php
/*
 * Password hashing with PBKDF2.
 * Author: havoc AT defuse.ca
 * www: https://defuse.ca/php-pbkdf2.htm
 */

// These constants may be changed without breaking existing hashes.
define("PBKDF2_HASH_ALGORITHM", "sha256");
define("PBKDF2_ITERATIONS", 1000);
define("PBKDF2_SALT_BYTES", 24);
define("PBKDF2_HASH_BYTES", 24);

define("HASH_SECTIONS", 4);
define("HASH_ALGORITHM_INDEX", 0);
define("HASH_ITERATION_INDEX", 1);
define("HASH_SALT_INDEX", 2);
define("HASH_PBKDF2_INDEX", 3);

function create_hash($password)
{
    // format: algorithm:iterations:salt:hash
    $salt = base64_encode(mcrypt_create_iv(PBKDF2_SALT_BYTES, MCRYPT_DEV_URANDOM));
    return PBKDF2_HASH_ALGORITHM . ":" . PBKDF2_ITERATIONS . ":" .  $salt . ":" . 
        base64_encode(pbkdf2(
            PBKDF2_HASH_ALGORITHM,
            $password,
            $salt,
            PBKDF2_ITERATIONS,
            PBKDF2_HASH_BYTES,
            true
        ));
}

function validate_password($password, $good_hash)
{
    $params = explode(":", $good_hash);
    if(count($params) < HASH_SECTIONS)
       return false; 
    $pbkdf2 = base64_decode($params[HASH_PBKDF2_INDEX]);
    return slow_equals(
        $pbkdf2,
        pbkdf2(
            $params[HASH_ALGORITHM_INDEX],
            $password,
            $params[HASH_SALT_INDEX],
            (int)$params[HASH_ITERATION_INDEX],
            strlen($pbkdf2),
            true
        )
    );
}

// Compares two strings $a and $b in length-constant time.
function slow_equals($a, $b)
{
    $diff = strlen($a) ^ strlen($b);
    for($i = 0; $i < strlen($a) && $i < strlen($b); $i++)
    {
        $diff |= ord($a[$i]) ^ ord($b[$i]);
    }
    return $diff === 0; 
}

/*
 * PBKDF2 key derivation function as defined by RSA's PKCS #5: https://www.ietf.org/rfc/rfc2898.txt
 * $algorithm - The hash algorithm to use. Recommended: SHA256
 * $password - The password.
 * $salt - A salt that is unique to the password.
 * $count - Iteration count. Higher is better, but slower. Recommended: At least 1000.
 * $key_length - The length of the derived key in bytes.
 * $raw_output - If true, the key is returned in raw binary format. Hex encoded otherwise.
 * Returns: A $key_length-byte key derived from the password and salt.
 *
 * Test vectors can be found here: https://www.ietf.org/rfc/rfc6070.txt
 *
 * This implementation of PBKDF2 was originally created by https://defuse.ca
 * With improvements by http://www.variations-of-shadow.com
 */
function pbkdf2($algorithm, $password, $salt, $count, $key_length, $raw_output = false)
{
    $algorithm = strtolower($algorithm);
    if(!in_array($algorithm, hash_algos(), true))
        die('PBKDF2 ERROR: Invalid hash algorithm.');
    if($count <= 0 || $key_length <= 0)
        die('PBKDF2 ERROR: Invalid parameters.');

    $hash_length = strlen(hash($algorithm, "", true));
    $block_count = ceil($key_length / $hash_length);

    $output = "";
    for($i = 1; $i <= $block_count; $i++) {
        // $i encoded as 4 bytes, big endian.
        $last = $salt . pack("N", $i);
        // first iteration
        $last = $xorsum = hash_hmac($algorithm, $last, $password, true);
        // perform the other $count - 1 iterations
        for ($j = 1; $j < $count; $j++) {
            $xorsum ^= ($last = hash_hmac($algorithm, $last, $password, true));
        }
        $output .= $xorsum;
    }

    if($raw_output)
        return substr($output, 0, $key_length);
    else
        return bin2hex(substr($output, 0, $key_length));
}
?>

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

عادةً ما أستخدم SHA1 والملح مع معرف المستخدم (أو بعض المعلومات الأخرى الخاصة بالمستخدم) ، وأحيانًا أستخدم ملحًا ثابتًا (لذلك لدي جزأين للملح).

يعتبر SHA1 الآن أيضًا معرضًا للخطر إلى حد ما ، ولكن بدرجة أقل بكثير من MD5. باستخدام ملح (أي ملح) ، فأنت تمنع استخدام عام طاولة قوس قزح لمهاجمة التجزئة الخاصة بك (حقق بعض الأشخاص نجاحًا في استخدام Google كنوع من طاولة قوس قزح من خلال البحث عن التجزئة). يمكن للمهاجم أن يولد طاولة قوس قزح باستخدام الملح ، ولهذا السبب يجب أن تضم ملحًا خاصًا بالمستخدم. وبهذه الطريقة ، سيتعين عليهم إنشاء طاولة قوس قزح لكل سجل في نظامك ، وليس فقط لنظامك بالكامل! مع هذا النوع من التمليح ، حتى MD5 آمن بشكل لائق.

SHA1 ويجب أن يكون الملح كافياً (اعتمادًا ، بطبيعة الحال ، على ما إذا كنت ترميز شيئًا ما فورت نوكس أو نظام تسجيل الدخول لقائمة التسوق الخاصة بك) في المستقبل المنظور. إذا لم يكن SHA1 جيدًا بما يكفي لك ، فاستخدم SHA256.

فكرة الملح هي رمي نتائج التجزئة عن التوازن ، لذلك القول. من المعروف ، على سبيل المثال ، أن MD5 Hash لسلسلة فارغة d41d8cd98f00b204e9800998ecf8427e. لذا ، إذا كان شخص ما لديه ذاكرة جيدة ، فسيرى هذا التجزئة ويعرف أنه تجزئة سلسلة فارغة. ولكن إذا كانت السلسلة مملحة (على سبيل المثال ، مع السلسلة "MY_PERSONAL_SALT") ، التجزئة لـ" السلسلة الفارغة "(أي"MY_PERSONAL_SALT") يصبح aeac2612626724592271634fb14d3ea6, ، ومن ثم غير أوال إلى الخلفية. ما أحاول قوله ، من الأفضل استخدامه أي الملح ، من عدم ذلك. لذلك ، ليس من الأهمية بمكان معرفة أيّ الملح للاستخدام.

هناك في الواقع مواقع الويب التي تفعل هذا فقط - يمكنك إطعامه (MD5) تجزئة ، وهو يبصق نصًا عاديًا معروفًا يولد هذا التجزئة المعينة. إذا تمكنت من الوصول إلى قاعدة بيانات تخزن MD5 ، فسيكون من التافهة أن تدخل التجزئة للمشرف إلى مثل هذه الخدمة ، وتسجيل الدخول. ولكن ، إذا كانت كلمات المرور مملحة ، فستصبح مثل هذه الخدمة هذه الخدمة غير فعال.

أيضا ، يعتبر التثقيب المزدوج بشكل عام طريقة سيئة ، لأنه يقلل من مساحة النتائج. جميع التجزئة الشعبية ثابتة. وبالتالي ، يمكن أن يكون لديك فقط قيم محدودة لهذا الطول الثابت ، وتصبح النتائج أقل تنوعًا. هذه استطاع تعتبر شكلاً آخر من أشكال التمليح ، لكنني لا أوصي به.

حسنًا ، يجب أن يكون الملح الملح في النسيج فريدًا ، لذا دعنا ننشئه

   /**
     * Generating string
     * @param $size
     * @return string
     */
    function Uniwur_string($size){
        $text = md5(uniqid(rand(), TRUE));
        RETURN substr($text, 0, $size);
    }

كما نحتاج إلى التجزئة التي استخدمها SHA512 إنه الأفضل وهو في PHP

   /**
     * Hashing string
     * @param $string
     * @return string
     */
    function hash($string){
        return hash('sha512', $string);
    }

حتى الآن يمكننا استخدام هذه الوظائف لإنشاء كلمة مرور آمنة

// generating unique password
$password = Uniwur_string(20); // or you can add manual password
// generating 32 character salt
$salt = Uniwur_string(32);
// now we can manipulate this informations

// hashin salt for safe
$hash_salt = hash($salt);
// hashing password
$hash_psw = hash($password.$hash_salt);

الآن نحتاج إلى حفظ في قاعدة البيانات القيمة المتغيرة $ hash_psw ومتغير $ salt

وللأذن ، سنستخدم نفس الخطوات ...

إنها أفضل طريقة لتأمين كلمات مرور عملائنا ...

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

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top