الگوریتم های رمز نامتقارن و تولید امضای دیجیتال
  در این مقاله با یک مثال کاربردی به معرفی الگوریتم های رمز نامتقارن و تولید امضای دیجیتال خواهم پرداخت
   C#
   ۲۳۸۹۴
   دانلود
   مرتضی صحراگرد
   ۱۳۸۹/۵/۳
ارسال لینک صفحه برای دوستان ارسال لینک صفحه برای دوستان  اضافه کردن به علاقه مندیها اضافه کردن به علاقه مندیها   نسخه قابل چاپ نسخه قابل چاپ

 

مقدمه:

الگوریتم های رمزنگاری داده ها به طور کلی به دو دسته تقسیم می شوند. دسته اول الگوریتم های رمز متقارن (Symmetric) و دسته دوم الگوریتم های رمز نامتقارن (Asymmetric) می باشند.

الگوریتم های رمز متقارن:

به طور کلی این دسته الگوریتم های بر اساس یک کلید (یا به عبارت دیگر یک کلمه یا عبارت رمز) داده ها را رمز نگاری (Encrypt) می کنند. ویژیگی خاص اینگونه الگوریتم ها این است که با همان کلید می توان داده ها را رمز گشایی (Decrypt) نمود.

اینگونه الگوریتم ها استفاده های فراوانی در دنیای اطلاعات دارند.

الگوریتم های رمز نامتقارن:

دسته دوم الگوریتم های رمز نامتقارن می باشند که استفاده های بسیار جالبی دارند. در اینگونه رمزنگاری ها، کلید رمز از دو قسمت تشکیل شده است.

این قسمت ها عبارتند از:

  •  کلید عمومی (Public Key)
  •  کلید خصوصی (Private Key)

ویژگی منحصر به فرد الگوریتم های رمز نامتقارن، این است که عمل رمز نگاری با استفاده از کلید عمومی انجام می شود و عمل رمز گشایی با استفاده از کلید خصوصی. در نتیجه کلید عمومی همانگونه که از عنوان آن مشخص است می توان در دسترسی عموم قرار داد ولی کلید خصوصی بسیار محرمانه می باشد (در ادامه مقاله نحوه تولید این کلید ها را فرا خواهید گرفت)

فرض کنید نرم افزاری تولید نموده اید که بر روی رایانه های مختلفی در سرتاسر جهان نصب شده است و قرار است بر اساس یک زمانبندی یا درخواست کاربر، اطلاعات محرمانه ای از رایانه ی کاربر به سرور شما ارسال شود. بدیهی است که این اطلاعات باید به شکل رمزنگاری شده ای برای شما ارسال شود تا اگر در بین راه به دست افراد بدخواهی افتاد، نتوانند به اطلاعات اصلی دسترسی پیدا کنند.

برای انجام این کار می توان از الگوریتم های رمز نگاری متقارن استفاده نمود. بدین ترتیب اطلاعات بر روی سیستم کاربر رمز شده و برای شما ارسال می شود. اما مشکلی که اینجا وجود دارد این است که برای اینکه اطلاعات به روش متقارن بر روی رایانه کاربر رمزنگاری شوند، طبق تعریف ابتدای مقاله باید کلید رمز را در داخل نرم افزار کاربر قرار دهید و این موضوع می تواند بسیار مشکل ساز شود. زیرا در صورتی که کاربر بتواند به هر نحوی به کلید رمز دسترسی پیدا کند، می تواند اطلاعات رمزنگاری شده را رمزگشایی نماید!

اینجاست که الگوریتم های رمز نامتقارن نمود پیدا می کنند. شما می توانید اطلاعات را با استفاده از کلید عمومی بر روی رایانه کاربر رمز نمایید. همانطور که قبلا ذکر شده، کلید عمومی فقط می تواند جهت رمز نمودن اطلاعات استفاده شود و به هیچ عنوان نمی تواند اطلاعات رمز شده را رمزگشایی کند. پس از اینکه اطلاعات برای شما ارسال شد، شما می توانید براحتی و توسط کلید خصوصی اطلاعات را رمزگشایی نمایید.

دو کلاس بسیار مشهوری که جهت رمزنگاری نامتقارن استفاده می شوند عبارتند از RSACryptoServiceProvider و DSACryptoServiceProvider.

در این مقاله نحوه استفاده از کلاس RSACryptoServiceProvider را جهت تولید کلید ها، رمز نگاری و رمز گشایی داده ها و تولید امضای دیجیتال را ملاحظه خواهید نمود.

نکته:

اندازه کلید می تواند از 384 بیت تا 16384 بیت باشد. بدیهی است که هر چقدر اندازه کلید بزرگتر باشد الگوریتم رمز قدرتمند تر می باشد و البته زمان لازم جهت رمزنگاری و رمز گشایی بیشتر شده و اندازه داده های رمز شده نیز بزرگتر می شود. بنابراین بهتر است که با توجه به نیاز خود اندازه کلید را انتخاب نمایید (اندازه کلید به صورت 8 بیتی اضافه می شود)

قدم اول برای استفاده از کلاس RSACryptoServiceProvider تولید کلید های خصوصی و عمومی می باشد.

در قطعه کد زیر نحوه ی تولید کلید عمومی و کلید خصوصی را ملاحظه می نمایید.

RSACryptoServiceProvider provider = new RSACryptoServiceProvider(1024);
string publicKey = provider.ToXmlString(false);
string privateKey = provider.ToXmlString(true);

اندازه کلید مورد نظر خودمان را (در این مثال 1024) به عنوان سازنده به کلاس RSACryptoServiceProvider ارسال نموده ایم. کلیدهای عمومی و خصوصی به شکل تصادفی و منحصر به فرد تولید می شوند. در قسمت زیر نمونه ای از این کلید ها را ملاحظه می نمایید.

کلید عمومی:

<RSAKeyValue><Modulus>

nHBNl8IhYdhR1ygWch7q4GhyRR58Jl9zrtujQQTGdB5EhmhNa029+pRdIb0iX7q0nQmDwMQf+oz4kNJSbsoxrlXrVLoEk4yYE1BA1+

XaqHzs5ETn1F5+CbG7tiqilaOeDdfPcOusG6YuLukUkiOEat5WxnycpOIqPcibpXKidRM=

</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>

کلید خصوصی:

<RSAKeyValue><Modulus>

nHBNl8IhYdhR1ygWch7q4GhyRR58Jl9zrtujQQTGdB5EhmhNa029+pRdIb0iX7q0nQmDwMQf+oz4kNJSbsoxrlXrVLoEk4yYE1BA1+

XaqHzs5ETn1F5+CbG7tiqilaOeDdfPcOusG6YuLukUkiOEat5WxnycpOIqPcibpXKidRM=

</Modulus><Exponent>AQAB</Exponent><P>2cV+oWcKpV5zvLuLsrbKNUZ7

OFn2/UDBkbxqK5hodVaRlIeTyR5t79Jg/ZRH/zeO4ODSeT+RK7GYtoR/iRzogw

==</P><Q>t+aNz+COWw1fA3nKtAjh9+iyHbQk8PZUlvGX+1+HMGjZ+kRT8cy6KEN9wlA0jRj3MXEWfSw0Xz4UyKeAFJP8MQ==</Q><DP>

l9bDL0iIPLt5mStvASHAJZtKCQV5WCVRkgq8QD9Y/g9pHBXX7lAAOUoHhGdiN8oGHjfDqPSwhLWklAYYYoK8fw==</DP><DQ>

Ena/fkOZh2LMS1kLFRBfP7jJSVow61CQJaeUDtUEicO9PvdlRj274xcDpWLQI+qBxyEHlQG/MGDXTV4j6e0BwQ==</DQ>

<InverseQ>XzVMppkHB6s0X39Zd+Fm7Xj8/XqmvXTF62rFvcukYgYgV6YaiH2eg2XTBVqNVq0y2RBytpiMdq7pl4kpe1OWXg==

</InverseQ><D>GW+pLiPCicZCiFlcTPH5/sL80YBDb3nVtXjA8rF0Ey1YtwH+lJPvb+7vtayrCiWxeFcztQQuru58/
A82mA0IRq8iGv64u4RPLbA+LrAcEypkDnqHrBWVc8O1FrAB7zt4F6

sHiCcFOJTCH0aTKu+K4IjLwbkv+SCVxSArpysYnAE=</D></RSAKeyValue>

در قسمت زیر نحوه ی رمز نمودن اطلاعات با استفاده از کلید عمومی را ملاحظه می نمایید.

RSACryptoServiceProvider provider = new RSACryptoServiceProvider();
 
//Use public key to encrypt data
provider.FromXmlString("Here is public key...");
 
byte[] data = Encoding.UTF8.GetBytes("Hi, Here is sample data for encryption -- 30sharp.com");
 
byte[] encryptedData = provider.Encrypt(data, true);

تذکر:

همانطور که ملاحظه می کنید، ما مقدار true را به عنوان دومین پارامتر برای متد Encrypt ارسال نموده ایم. اگر قصد دارید این برنامه بر روی سیستم عامل های قدیمی تر از ویندوز XP نیز اجرا شود باید مقدار false را برای این پارامتر ارسال نمایید.

و اکنون زمان رمز گشایی داده ها با استفاده از کلید خصوصی فرار رسیده است.

RSACryptoServiceProvider provider = new RSACryptoServiceProvider();
 
//Use private key to decrypt data
provider.FromXmlString("Here is private key...");
 
byte[] data = provider.Decrypt(encryptedData, true);

تذکر:

تذکر قبلی در مورد متد Decrypt نیز صادق است.

تولید امضای دیجیتال:

یکی از جالب ترین امکاناتی که الگوریتم های رمز نامتقارن فراهم می آورند، امضای دیجیتال می باشد. امضای دیجیتال شناسه ای می باشد که با استفاده از آن می توان پی برد که اطلاعاتی که برای شما ارسال شده است از سوی شخص مورد نظر بوده است یا خیر.

در حقیقت امضای دیجیتال با استفاده از کلید خصوصی و بر اساس داده های مشخصی تولید می شود و سپس اشخاصی که کلید عمومی را در دسترس دارند می توانند تشخیص دهند که اطلاعات از سوی شما ارسال شده است یا خیر.

البته محتوای امضای دیجیتال هرگز توسط کلید عمومی قابل رمزگشایی نیست ولی می توان مشخص نمود که اطلاعات براستی از طرف شما ارسال شده است.

فرض کنید قرار است که فایل متنی را از طریق یک وب سرویس یا روش POST یا هر روش دیگر ارسال نمایید. چگونه دریافت کننده می تواند اطمینان حاصل نماید که اطلاعات از طریق شخص شما ارسال شده است؟ این روش امروزه در برخی تبادلات بین فروشگاه های اینترنتی و بانک ها مورد استفاده قرار می گیرد. بانک ها با استفاده از این روش می توانند مطمئن شوند که تراکنش های ارسال شده به آن ها حتما از طریق فروشنده ی مشخص انجام شده است.

برای تولید امضای دیجیتال نیاز به داده ی مورد نظر (محتوای یک فایل یا یک ایمیل یا تراکنش بانکی و یا هر چیز دیگری) و همچنین کلید خصوصی می باشد.

نحوه ی تولید امضای دیجیتال را ملاحظه می نمایید.

RSACryptoServiceProvider MySigner = new RSACryptoServiceProvider();
 
byte[] data = Encoding.UTF8.GetBytes("Hi, Here is sample data for Signature -- 30sharp.com");
MySigner.FromXmlString("Here is private key...");
byte[] signature = MySigner.SignData(data, new SHA1CryptoServiceProvider());

اکنون کافی است که داده ی مورد نظر را به همراه امضای تولید شده برای شخص مورد نظر خود ارسال نمایید.

شخص مورد نظر که کلید عمومی را در دسترس دارد می تواند با استفاده از امضای دیجیتال شما و داده ی دریافت شده، مشخص نماید که داده ها از سمت شما ارسال شده است یا خیر!

RSACryptoServiceProvider provider = new RSACryptoServiceProvider();
 
provider.FromXmlString("Here is public key...");
byte[] data = Encoding.UTF8.GetBytes("Hi, Here is sample data for Signature -- 30sharp.com");
byte[] signature = //Has sent for us
 
if (provider.VerifyData(data, new SHA1CryptoServiceProvider(), signature))
    MessageBox.Show("Signature is verified");
else
    MessageBox.Show("Signature is not verified!");

قطعه کد کامل این مقاله از لینک بالای صفحه قابل دریافت می باشد.