ASP.NET Core مجهز به یک سیستم جدید و بهبود یافته حفاظت از داده هاست. این سیستم جایگزین نسخه های قبلی مورد استفاده در ASP.NET شده است. میان افزار کوکی و اعتبار سنجی anti-forgery (ضد جعل) هر دو از این سیستم برای محافظت از کوکی ها و توکن ها استفاده می کنند. همچنین می توان از این سیستم برای محافظت از داده های حساس برنامه استفاده کرد. بیایید مرور کنیم که چه چیزی این سیستم را راه حل بهتری برای محافظت از داده ها می کند. این برنامه به گونه ای طراحی شده است که پیکربندی آن با API هایی که استفاده از آنها با سادگی انجام می شود، برای توسعه دهندگان ساده باشد، و با تنظیمات پیش فرض که به راحتی در دسترس است، ارائه می شود. به طور پیش فرض، این سیستم؛ از AES-256 برای الگوریتم رمزگذاری متقارن و SHA-256 برای اعتبار سنجی استفاده می کند. در این سیستم مدیریت کلیدها، مانند ذخیره سازی و رمزگذاری کلیدها، به صورت خودکار انجام می شود. این سیستم محیط عملیاتی را شناسایی می کند و بر اساس آن تنظیمات پیش فرض را اعمال می کند.
به عنوان مثال، اگر سیستم عامل شما ویندوز است، کلیدها در آغاز با استفاده از DPAPI رمزگذاری می شوند. اگر مکانیسمهای رمزگذاری کلید داخلی مناسب نیستند، یک توسعهدهنده میتواند یک گزینه شخصی سازی شده را پیکربندی کند. طول عمر کلید پیش فرض 90 روز است. بنابراین پس از انقضای آن، یک کلید جدید برای رمزگذاری استفاده می شود. این به شما امکان چرخش خودکار کلید را می دهد. کلیدهای قدیمی نیز برای پشتیبانی از رمزگشایی دادههایی که با آن کلیدها رمزگذاری شدهاند، نگهداری میشوند.
سیستم حفاظت از داده ها همچنین به طور پیش فرض برنامه ها را از یکدیگر جدا می کند، بنابراین آنها نمی توانند داده های محافظت شده یکدیگر را بخوانند. اگر هر یک از این تنظیمات پیش فرض نیاز به تغییر داشته باشد، می توان آن را با API های پیکربندی انجام داد. بیایید نگاهی به نحوه استفاده از پشته رمزنگاری جدید بیندازیم. ما یک متد Web API را که دادههای حساسی را دریافت میکند، نشان میکنیم، و آن را با استفاده از APIهای حفاظت از داده رمزگذاری میکنیم.
بیایید به سراغ متد ConfigureServices کلاس Startup برویم. و در اینجا، سرویس حفاظت از داده ها را اضافه می کنیم.
اگر قصد داریم از تنظیمات پیکربندی پیش فرض استفاده کنیم، این تنها کاری است که باید انجام دهیم. یعنی فقط متد زیر را فراخوانی می کنیم.
services.AddDataProtection()
اگر بخواهیم پیش فرض ها را لغو کنیم، می توانیم از Fluent API استفاده کنیم.
به عنوان مثال، من می توانم DisableAutomaticKeyGeneration را برای غیرفعال کردن چرخش کلید صدا کنم. برای فعال شدن این امکان باید فضای نام Microsoft.AspNetCore.DataProtection را در بالای کد اضافه کنیم. همچنین میتوانم طول عمر کلید پیشفرض را با استفاده از مشخصه SetDefaultKeyLifetime از 90 روز به مقدار دیگری تغییر دهم. اجازه دهید آن را به 14 روز تغییر دهیم.
services.AddDataProtection()
.DisableAutomaticKeyGeneration()
.SetDefaultKeyLifetime(new TimeSpan(14, 0, 0, 0));
حال، بیایید به کنترلر ValuesController برویم، جایی که میخواهیم متدی را اضافه کنیم که برخی از دادههای سری/مخفی را برمیگرداند. سیستم حفاظت از داده ها از دو رابط مهم IDataProtectionProvider و IDataProtector استفاده می کند.
بیایید IDataProtector را در بالای کلاس خود تعریف (declare) کنیم. ما باید یک سازنده برای کنترلر خود اضافه کنیم. و اکنون می توانیم IDataProtectionProvider را با استفاده از تزریق وابستگی اضافه کنیم. Provider (ارائه دهنده) را نمی توان مستقیماً استفاده کرد. ابتدا باید یک شی از نوع Protector (محافظ) ایجاد کند. حال محافظ، مسئول رمزگذاری و رمزگشایی داده ها است.
IDataProtector _protector;
public ValuesController(IDataProtectionProvider provider)
{
_protector = provider.CreateProtector("Tutorial.AspNetSecurity.WebApi.Controllers.ValuesController", new string[] { "Tenant1" });
}
بیایید آبجکت Protector را با استفاده از روش CreateProtector ایجاد کنیم. پارامتر رشته ای که ما به این متد ارسال می کنیم یک رشته مرتبط با کلاس یا کنترلرهدف است که باید منحصر به فرد نیز باشد. استفاده از فضای نام و نوع کلاس برای جلوگیری از تداخل نامگذاری، روش مناسبی است. پس بیایید فضای نام کامل را تایپ کنیم که Tutorial.AspNetSecurity.WebApi.Controllers و در نهایت عنوان نوع کلاس خود که ValuesController است را تایپ کنیم.
این رشته هدف، ایزولهسازی مورد نیاز ما را فراهم میکند تا سایر کامپوننت های برنامه نتوانند دادهها را بخوانند، حتی اگر از کلید رمزنگاری یکسانی استفاده کنند. به این دلیل که با این روال که انجام شد، یک کلید فرعی با متصل شدن کلید اصلی به رشته هدف تولید می شود. کلید فرعی همان چیزی است که برای رمزگذاری و رمزگشایی استفاده می شود.
همچنین میتوانید به صورت زنجیر وار رشته های هدف دیگری را نیز اضافه کنید، و میتوانید رشته های هدف ثانویه را با یک آرایه ای از نوع رشتهای اضافه کنید. کدی که بالاتر نوشته شده است چیزی است که نتیجه گفته های ما خواهد بود.
این در صورتی مفید است که چندین رشته هدف ثانویه را در برنامه خود پشتیبانی می کنید و می خواهید ایزولهسازی را بین آنها حفظ کنید. اکنون که ما protector (محافظ) خود را پیاده سازی کرده ایم، بیایید متدی را اضافه کنیم که مجموعه ای از شناسه های کاربر را برمی گرداند. و ما نام آن متد را GetUserIds می نامیم. نوع این متد HttpGet خواهد بود. و برای Route مربوط به متد UserIds را انتخاب می کنیم. ما نمیخواهیم دادههای حساس شناسه ما افشا شود، بنابراین آنها را رمزگذاری میکنیم. تنها کاری که باید انجام دهم این است که متد Protect شی محافظ (protector) خود را فراخوانی کرده و رشته ای را که باید رمزگذاری کنیم، ارسال کنیم.
[HttpGet]
[Route("UserIds")]
public IEnumerable<string> GetUserIds()
{
var secretId1 = _protector.Protect("ST123");
var secretId2 = _protector.Protect("FC456");
return new string[] { secretId1, secretId2 };
}
برای ساده نگه داشتن کارها، شناسه کاربری را داخل کد به صورت ثابت قرار می دهیم. و ما همین کار را با شناسه کاربری دیگر انجام خواهیم داد. و در نهایت، متد ما یک آرایه رشته ای را برمی گرداند که مقادیر رمزگذاری شده را در خود نگه می دارد. اکنون بیایید نحوه عملکرد رمزگشایی را بررسی کنیم. من متد دیگری را اضافه می کنم که یک شناسه رمزگذاری شده را می گیرد و یک مقدار متن ساده را برمی گرداند. نوع این متد نیز HttpGet خواهد بود. و در ادامه برای Route، از PlainTextId استفاده خواهیم کرد. ما از همان شی محافظ استفاده می کنیم، اما این بار متد Unprotect را فراخوانی می کنیم و مقدار مورد نیاز برای رمزگشایی را وارد می کنیم.
[HttpGet]
[Route("PlainTextId")]
public string GetPlainTextId(string encryptedId)
{
var plaintext = _protector.Unprotect(encryptedId);
return plaintext;
}
و در نهایت، مقدار متن ساده را برمی گردانیم. توجه به این نکته مهم است که فقط یک محافظ داده که از همان ارائه دهنده داده با پارامترهای هدف یکسان ایجاد شده است، می تواند داده ها را رمزگشایی کند. متد Unprotect نیز مقدار رمزگذاری شده را می گیرد و نسخه اصلی را برمی گرداند. بیایید پروژه Web API را اجرا کنیم. و ما به سراغ اند پوینت UserIds خود خواهیم رفت. در اینجا آرایه رشته ای ما با دو مقدار متن رمزی ناخوانا آمده است. این رشته ها با استفاده از یک محافظ داده با الگوریتم متقارن پیشفرض رمزگذاری شدند.
من ادامه میدهم و یکی از این مقادیر را کپی میکنم، بنابراین میتوانیم آن را رمزگشایی کنیم. بیایید نقطه پایانی متن ساده را فراخوانی کنیم، که انتظار ورودی یک پارامتر شناسه رمزگذاری شده را دارد، و من مقدار رمزگذاری شده ای را که به تازگی کپی کردم، جایگذاری می کنم. نتیجه مقدار متن ساده اصلی ما است، بنابراین می دانیم که رمزگشایی کار می کند.
بیایید ببینیم اگر چند تا از این کاراکترها را از مقدار رمزگذاری شده حذف کنم چه اتفاقی میافتد.
می بینید که یک خطای رمزنگاری ایجاد شده است.
برای خواندن و رمزگشایی داده ها به متن رمزگذاری شده معتبر و محافظ داده درست نیاز داریم.
برای دریافت کد برنامه روی پیوند زیر کلیک کنید.