English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

التحقق من التحقق الافتراضي لـ IPasswordHasher من Microsoft.Identity في Asp.net وطرق الاستخدام

بالطبع، من يعرف نظام التحقق MS Identity يعرف دور UserManager، وهو مدير التسلسل في النظام، حيث يحدد سلوك المستخدم لمساعدتنا في إدارة معلومات المستخدم، معلومات الأدوار، ومعالجة الكلمات المرور. ويتم تنفيذ ذلك في UserStore، حيث يمكننا تنفيذها من خلال ما تم تعريفه مثل IUserStore،IUserPasswordStore،IRoleStore وما إلى ذلك. يمكننا بناءً على مجموعة من سلوك المستخدم، تعريف معلومات المستخدم و بنية البيانات و تخزين البيانات. إذاً، بالنسبة لتشفير Password، يقدم MS تعريفًا كاملاً للسلوك، ويتم تسريع ذلك من قبل UserManager. على سبيل المثال،

UserManager.PasswordHasher.HashPassword(password)

تم تعريف PasswordHasher في واجهة UserManager كما يلي:

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

لذلك، ظهرت هذه المشكلة في تصديق كلمات المرور في تطبيقات متعددة:

على سبيل المثال، يتبع تطبيق A إجراء IPasswordHasher لتعريف طريقة التشفير المخصصة على شكل MD5 + salt، بينما يتبع تطبيق B PasswordHasher الافتراضي لـ Identity، حيث يمكن الحصول على الشيفرة التالية من خلال التجزئة:

لذلك، من أجل التكامل مع أنظمة التشفير المختلفة للمطالبات المختلفة، كان علي أن أقوم بتجزئة الشيفرة المصدرية للحصول على طريقة التشفير الافتراضية، وأحكم على تشفير أو التشفير للكلمات المرور بناءً على اسم التطبيق المختلف، أو بشكل مباشر من خلال طريقة معينة للتحقق من قاعدة البيانات والكلمة المرور المدخلة من المستخدم. دعونا نبدأ بعرض تنفيذ PasswordHasher الافتراضي لـ MS.

// تم تجزئة باستخدام JetBrains decompiler
// النوع: Microsoft.AspNet.Identity.Crypto
// جمع: Microsoft.AspNet.Identity.Core, إصدار=2.0.0.0, ثقافة=neutral, رمز المفتاح=31bf3856ad364e35
// MVID: E3A10FFD-023A-4BC3-AD53-32D145ABF1C9
// Assembly location: C:\Sport\NewProject\V2.0\Api\Fantasy.Sport\packages\Microsoft.AspNet.Identity.Core.2.2.1\lib\net45\Microsoft.AspNet.Identity.Core.dll
using System;
using System.Runtime.CompilerServices;
using System.Security.Cryptography;
namespace Microsoft.AspNet.Identity
{
 internal static class Crypto
 {
 private const int PBKDF2IterCount = 1000;
 private const int PBKDF2SubkeyLength = 32;
 private const int SaltSize = 16;
 public static string HashPassword(string password)
 {
  if (password == null)
  throw new ArgumentNullException("password");
  byte[] salt;
  byte[] bytes;
  using (Rfc2898DeriveBytes rfc2898DeriveBytes = new Rfc2898DeriveBytes(password, 16, 1000))
  {
  salt = rfc2898DeriveBytes.Salt;
  bytes = rfc2898DeriveBytes.GetBytes(32);
  }
  byte[] inArray = new byte[49];
  Buffer.BlockCopy((Array) salt, 0, (Array) inArray, 1, 16);
  Buffer.BlockCopy((Array) bytes, 0, (Array) inArray, 17, 32);
  return Convert.ToBase64String(inArray);
 }
 public static bool VerifyHashedPassword(string hashedPassword, string password)
 {
  if (hashedPassword == null)
  return false;
  if (password == null)
  throw new ArgumentNullException("password");
  byte[] numArray = Convert.FromBase64String(hashedPassword);
  if (numArray.Length != 49 || (int) numArray[0] != 0)
  return false;
  byte[] salt = new byte[16];
  Buffer.BlockCopy((Array) numArray, 1, (Array) salt, 0, 16);
  byte[] a = new byte[32];
  Buffer.BlockCopy((Array) numArray, 17, (Array) a, 0, 32);
  byte[] bytes;
  using (Rfc2898DeriveBytes rfc2898DeriveBytes = new Rfc2898DeriveBytes(password, salt, 1000))
  bytes = rfc2898DeriveBytes.GetBytes(32);
  return Crypto.ByteArraysEqual(a, bytes);
 }
 [MethodImpl(MethodImplOptions.NoOptimization)]
 private static bool ByteArraysEqual(byte[] a, byte[] b)
 {
  if (object.ReferenceEquals((object) a, (object) b))
  return true;
  if (a == null || b == null || a.Length != b.Length)
  return false;
  bool flag = true;
  for (int index = 0; index < a.Length; ++index)
  flag &= (int) a[index] == (int) b[index];
  return flag;
 }
 }
}

قد يسأل شخص ما كيف يمكن استخدامه لهذه الأكواد المصدر. سأقوم بشرح هذا الموضوع بشكل مختصر.

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

عند تسجيل المستخدم ومراجعة كلمة المرور، يتم تشفير كلمة المرور من خلال طريقة HashPassword المذكورة أعلاه، لذا، في PasswordHasher المخصص الجديد الخاص بي، عند مقارنة كلمة المرور المدخلة مع كلمة المرور التي تم تخزينها في قاعدة البيانات بعد معالجتها من قبل hasher، لماذا لا أستخدم HashPassword لتشفير إدخال المستخدم مباشرةً؟ لذا، طريقة VerifyHashedPassword (تترجم إلى التحقق) الخاصة بي هي مقارنة Pwd في قاعدة البيانات بنتيجة التشفير التي تم تحقيقها من قبل hasher. ولكن، النتيجة هي أن نفس السلسلة من الأحرف تنتج دائمًا نتيجة تشفير مختلفة، وليس مثل md5 + salt من قبل.

لذا، الأخير الذي يجب قوله هو أنك يمكنك استخدام طريقة التشفير الخاصة بـ Microsoft Identity (الHasher المذكور أعلاه) مباشرةً، عند مقارنة إدخال المستخدم بنتيجة التخزين المشفرة المسبق في قاعدة البيانات باستخدام طريقة VerifyHashedPassword(). يمكنك أيضًا استخدام هذا خوارزمية التشفير حتى إذا لم تستخدم التحقق من الهوية.

هذا هو نهاية محتويات هذا المقال، آمل أن تكون محتويات هذا المقال قد ساعدتكم في التعلم أو العمل، وآمل أيضًا أن تدعموا تعليمات النطق!

البيان: محتويات هذا المقال تم جمعها من الإنترنت، وتحتفظ بالحقوق القانونية لأصحابها، تم جمع المحتويات من قبل المستخدمين عبر الإنترنت الذين قدموا مساهماتهم الخاصة وأرسلواها بشكل مستقل، ولا تملك هذا الموقع حقوق الملكية، ولا يتم تعديل المحتويات بشكل يدوي، ولا يتحمل هذا الموقع أي مسؤولية قانونية متعلقة بذلك. إذا كنت قد وجدت محتويات مشبوهة بالنسبة لحقوق النسخ، فنرجو منك إرسال بريد إلكتروني إلى: notice#oldtoolbag.com (الرجاء استبدال # ب @ عند إرسال البريد الإلكتروني) للإبلاغ، وتقديم الدليل المتعلق، وسنقوم بإزالة المحتويات المشبوهة التي تم الكشف عنها على الفور.

سيكون ممتازاً لك