1394/10/17 21:58 رمزنگاری نامتقارن با الگوریتم RSA به کمک فایل های cer و pfx
حاجی شریفی
مؤسس سایت
 
سلام
در مطلب فعلی میخواهیم مثال ساده از رمزنگاری نامتقارن را در حالی خاص بررسی و مشاهده کنیم.



بعنوان مقدمه باید عرض کنم که اغلب افراد با الگوریتم های متقارن آشنا هستند، مانند گذرواژه ای که روی فایل zip میگذاریم و درآینده برای باز کردن آن فایل zip به همان گذرواژه اولیه نیاز داریم، این یک الگوریتم متقارن است، از جمله معروف ترین الگوریتم های متقارن میتوان به DES و AES اشاره کرد.

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

این همان روشی است که در ارتباطات SSL و درپروتکل های https و ftps استفاده میشود و مزیت های بسیار زیادی دارد... که دراین زمان، خارج از حوصله بیان ام است...
(
فقط اشاره کوچکی داشته باشم ...
بکمک این الگوریتم ما میتوانیم کلید عمومی را به همه بدهیم تا هرچیزی که خواستند برای ما ارسال کنند را با آن رمز کنند ،
نکته جالب آن است که با داشتن کلید خصوصی، این فقط و فقط ما هستیم که میتوانیم محتوای بسته را رمزگشایی و مشاهده کنیم !
خیلی جالب است !
)

این جفت کلید عمومی و خصوصی ، بطور معمول به همراه یک سری مشخصات درفایل هایی مانند cer.* و pvk.* و snk.* و pfx.* و... نگه داری میشود.

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

public static byte[] Encrypt_With_PublicKey(string PublicKeyFile, byte[] rawData)
{
var cert = new X509Certificate2(PublicKeyFile);
var rsa = (RSACryptoServiceProvider)cert.PublicKey.Key;
return rsa.Encrypt(rawData, false);
}


سپس کلید خصوصی را از فایل pfx خوانده و دیتا رمزشده را رمزگشایی کنیم:

public static byte[] Decrypt_With_PrivateKey(string PrivateKeyFile, byte[] cryptData)
{
var cert = new X509Certificate2(PrivateKeyFile, "123" ) ;
var rsa = (RSACryptoServiceProvider)cert.PrivateKey ;
return rsa.Decrypt(cryptData, false) ;
}


(برای تولید دستی فایل های cer و pfx میتوان از فرمان makecert.exe و pvk2pfx.exe استفاده کرد.)

دانلود سورس کد:
Simorgh.RSATest.zip
1394/10/19 17:3
h-e-r-o-e-s

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

حقیقت درکش برام یک مقداری مشکل هست ....

1394/10/19 18:55
حاجی شریفی
مؤسس سایت
 
سلام
نقل قول نوشته شده توسط: h-e-r-o-e-s

... می خواستم ببینم وقتی یک محتوایی با اس اس ال رمز میشه چجوری با یک پسورد دیگه دی کد میشه ...

نمیدانم بطور دقیق سوال و مشکل شما ریاضی است یا برنامه نویسی !

از نظر ریاضی فقط میتوانم ظاهر امر را تشریح کنم و از باطن آن اطلاع ندارم.
اگوریتمی داریم که میتواند دیتایی را با یک گذرواژه رمز کند ولی با همان گذرواژه نمیتوان رمزگشایی کرد! برای رمزگشایی یک گذرواژه دومی وجود دارد!
مانند آن است که فایلی را با کلمه "abc" رمز کنید ولی برای رمزگشایی آن دیگر "abc" بکار نیاید و نیاز به گذرواژه دوم مثلا "xyz" باشد...
هرچیزی را که با "abc" رمزمیکنید "xyz" بتواند آن را باز کند، یعنی دو گذرواژه مرتبط با هم وجود دارد یکی برای رمزکردن و یکی برای رمزگشایی ...
اینکه این الگوریتم ازنظر مبنای ریاضی چه طور کار میکند، نمیدانم.
فقط میدانم که زیرشاخه تحصیلی برای دانشجویان "ریاضیات محض" وجود دارد به نام "کد و رمز" که به مبانی همین مسائل میپردازد و تا حد دکتری هم پیش میرود.
برای اطلاعات بیشتر میتوانید لینک زیر را مطالعه کنید:
https://en.wikipedia.org/wiki/RSA_(cryptosystem)

اما اگر سوالات درحوزه برنامه نویسی و کارکرد ذاتی SSL است، خوب کمی ساده تر است.
بطور نمونه یک سرور https به راحتی اعتبارنامه و کلیدعمومی خود را دردسترس عموم قرار میدهد ...
هرکسی میتواند این کلید عمومی گرفته و اطلاعات خود را با آن رمزکرده و برای آن سرور https ارسال کند ...
چون کلید خصوصی فقط در اختیار همان سرور است هیچ رایانه و پراکسی و... در این مسیر نمیتواند اطلاعات را رمزگشایی کند ، میتواند آن را دست به دست کند ولی نمیتواند باز کند، مانند فایل zip ای که گذرواژه دارد و شما به من بدهید تا به کس دیگری بدهم، گرچه از زیر دست من رد میشود ولی چون رمز آن را ندارم نمیتوانم بازش کنم و فقط میتوانم به نفر بعدی بدهم (یا ندهم که ...)
بسته رمزگذاری شده به دست سرور اصلی که رسید خیلی راحت با کلید خصوصی خود (که به کسی نداده) بسته را رمزگشایی کرده و محتویات را میخواند.

امیدوارم به جواب تان رسیده باشید.
شب خوش
1395/02/01 6:1
حاجی شریفی
مؤسس سایت
 
سلام
باتوجه به پاره ای از مباحث که در خارج سایت پیش آمده بود، بهتر دیدم توضیحات اضافه ای را اینجا بطور عمومی منتشر کنم
==============
تعاریف پایه:
Private Key
مجموعه کامل کلید رمزنگاری و رمزگشایی اطلاعات است که فقط در اختیار یک نفر یا یک رایانه میباشد و انتشار پیدا نمیکند.
در جمله بندی ها بطور معمول با عبارت "فقط یک نفر میتواند ..." معادل است.

Public Key
بخشی از کلید رمزنگاری است که بطور عمومی منتشر میشود و هرکاری نمیتوان با آن انجام داد.
بطورنمونه در ارتباطات SSL در ابتدای Handshake (دست دادن) به راحتی منتشر شده و در اختیار هر رایانه ای قرار میگیرد.
در جمله بندی ها بطور معمول با عبارت "همه میتوانند ..." معادل است.

Certificate
شامل Public Key و یکسری اطلاعات اضافه هویتی است، مانند تاریخ اعتبار، نام، سایت، ایمیل و امضای صادر کننده اعتبار نامه و...
با وجود امضای صادرکننده، مانند یک مدرک و سند از صحت هویت رایانه است.
به عنوان نمونه اگر چند اعتبارنامه به نام google.com داشته باشیم از روی امضای اعتبار نامه میتوان گفت کدام اعتبار نامه و Public Key واقعا متعلق به google.com است.
شاید دیده باشید که برخی سایت های https در آدرس بار مروگرها قرمز نمایش داده میشوند، اعتبار نامه این سایت ها امضای مشخصی نداشته و قابل تایید صلاحیت نیست یا تاریخ آن منقضی شده است.


==============
مفهوم رمزنگاری نامتقارن
رمزنگاری نامتقارن همواره با Public Key رمزشده و با Private Key رمزگشایی میشود.
یعنی هرکسی میتواند اطلاعات خودش را تولید و در شبکه ارسال کند ولی فقط گیرنده نهایی (مالک Private Key) میتواند آن را باز کند و محتویاتش را بخواند.

==============
مفهوم امضای دیجیتال
این مفهوم به Hash اطلاعات بسیار نزدیک است.
حتما دوستان با مفاهیم CRC و MD5 و SHA1 آشنا هستند.
بطور معمول کدهای هش در ابتدای ارسال یک بسته (مانند Content-MD5 در HTTP) یا در انتهای ارسال یک بسته (مانند CRC32 در GZip) ارسال میشوند و گیرنده با محاسبه مجدد آن میتواند اطمینان پیدا کند اطلاعات در طول مسیر خراب نشده است و به درستی منتقل شده.
وجود این کدها در برخی پروتکل ها اختیاری و قابل حذف است (مانند Content-MD5 در HTTP) و در برخی موارد اجباری است. (مانند CRC32 در GZip)

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

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

==============
رمزنگاری با کلید خصوصی و رمزگشایی با کلید عمومی
این کار اشتباه بوده و منطق ندارد و بطور عادی توسط اکثر کتابخانه های آماده زبان های برنامه نویسی پشتیبانی نمیشود.
دلیل آن هم واضح است.
چرا باید یک نفر اطلاعات را طوری رمزکند که همگان کلید رمزگشایی (Public Key) آن را دارند؟! چه ارزشی دارد؟

شاید این مانند کاری است که سایت های عزیز هموطن در فایل های zip و rar خود انجام میدهند، فایل را رمزکرده و گذرواژه را در نام فایل قرار میدهند، آنها شاید دلیل خودشان را داشته باشند، ولی در دنیای امنیت اطلاعات ارزش خاصی ندارد.
دوستان باید کار ونیاز خودشان را با یکی از دوموردی که پیش از این در بالاتر توضیح داده شده بود پیاده سازی کنند.
1395/02/24 13:11
developzoom

 
سلام دوست عزیز آموزش خوبی بود موفق باشی دوست داشتی از سایت منم دیدن کن مرسی 
http://www.developzoom.com/

1395/02/29 13:22
h-e-r-o-e-s

 
سلام
سایت خوب و عالی دارید
1395/11/15 18:40
حاجی شریفی
مؤسس سایت
 
سلام
در مورد "امضای دیجیتال" صحبت کردیم ولی کدی ننوشتیم.
با توجه به گفتگویی که در خارج سایت پیش آمد، تصمیم گرفتم نمونه کد "امضای دیجیتال" را هم به همین تاپیک اضافه کنم.
کد زیر در همان برنامه قبلی کار خواهد کرد.

تولید امضا برای اطلاعات موجود با کلید خصوصی:
public static byte[] Sign_With_PrivateKey(string PrivateKeyFile, byte[] cryptData)
{
var cert = new X509Certificate2(PrivateKeyFile, "123" ) ;
var rsa = (RSACryptoServiceProvider)cert.PrivateKey;
return rsa.SignData(cryptData, new SHA1CryptoServiceProvider());
}


بررسی صحت امضا روی اطلاعات با کلید عمومی:
public static bool Verify_With_PublicKey(string PublicKeyFile, byte[] rawData, byte[] signData)
{
var cert = new X509Certificate2(PublicKeyFile);
var rsa = (RSACryptoServiceProvider)cert.PublicKey.Key;
return rsa.VerifyData(rawData, new SHA1CryptoServiceProvider(), signData);
}


موفق باشید.
1395/12/19 23:33
Persia

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

من با استفاده از دستورات cmd ، کلید عمومی و خصوصی ساختم ولی فقط رمز گذاری میکنه و موقع رمز گشایی ارور میده ، بنظرم کلید خصوصی من ایراد داره


makecert -sv PrivateKey.pvk -n "CN=Persia" PublicKey.cer -b 03/10/2017 -e 03/10/2020 -r

pvk2pfx -pvk PrivateKey.pvk -pi 123 -spc PublicKey.cer -pfx PrivateKey.pfx -f
1395/12/22 16:16
حاجی شریفی
مؤسس سایت
 
سلام
نقل قول نوشته شده توسط: Persia
...در مورد ساخت کلید عمومی و خصوصی هم یه آموزش بسازید...

اول باید عضرخواهی کنم در گیروداد نصب ویندوز و آمدن VS2017سوال شما را به موقع ندیدم...

دوم آنکه با دستوراتی شبیه این میتوانید فایل های مورد نظر را بسازید، دقت کنید که در حالیکه pi در pvk2pfx رمز فایل کلید خصوصی موجود(قبلی) را مشخص میکند ، po رمز فایل pfx جدید ساخته شده را مشخص میکند و دستورات شما هم احتمالا بدلیل فقدان sky و همچنین po به مشکل میخورده.

makecert.exe -n "CN=Persia" -sky exchange D:\PublicKey.cer -sv D:\PrivateKey.pvk
pvk2pfx.exe -pvk D:\PrivateKey.pvk -spc D:\PublicKey.cer -pfx D:\PrivateKey.pfx -pi 123 -po 123
مشکلی بود درخدمت هستم.
موفق باشید.
16 روز پیش
mahdi72

 
سلام میخواستم بپرسم که درحال حاظر قوی ترین و امن ترین الگوریتم رمزگزاری چی هستش؟ میخام یه فایل رو رمزگذاری کنم و فقط خودم بتونم دوباره رمزگشاییش کنم، دقیقا کاری که این باج افزارها میکنن.
15 روز پیش
حاجی شریفی
مؤسس سایت
 
سلام برادر !
نقل قول نوشته شده توسط: mahdi72
... دقیقا کاری که این باج افزارها میکنن ...

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

طبق تجربیات و تعامل هایم در سال های زیاد، اغلب این کار را کم اطلاع ترین افراد انجام میدهند.
بی جنبه ترین افراد که با خرده اطلاعات بی ارزشی میخواهند خودشان را مطرح کنند.
کاری به اعتقادات دینی هم نداشته باشیم باز کلام ارزشمندی است که مولی امیرالمومنین (ع) میفرمائید "آنچه را که برای خود نمی پسندی ، برای دیگران مپسند"
من که دوست ندارم کسی با هارد-دیسک من این کار را بکند. (؟!)

نقل قول نوشته شده توسط: mahdi72
...یه فایل رو رمزگذاری کنم و فقط خودم بتونم دوباره رمزگشاییش...

اگر هدف رفع نیازهای شخصی معمول است،
پیشنهاد میکنم از ZIP و 7Z و BitLocker استفاده کنید.

همین ZIP عادی که استفاده میکنیم از رمزنگاری پیشرفته AES-256 استفاده میکند که هیچ راهی جز امتحان گذرواژه های مختلف برای شکستنش وجود ندارد.
برای خیلی از موارد شما فایل هایتان را ZIP کنید و گذرواژه های طولانی روی آنها بگذارید بسیار ایمن ، راحت و دردسترس است.
برنامه های زیادی این فرمت را میشناسند وحتی خود Explorer ویندوز هم میتواند محتویات داخل ZIP را نشان تان دهد و...و...
ولی ایراداتی هم دارد.
اول) آنکه نام فایل ها در ZIP رمز نمیشود، یعنی بدون داشتن گذرواژه میتوان نام فایلها را مشاهده کرد.
دوم) در حجم بالا چند گیگ و چند ترابایت ، روشی بسیار کند است و مناسب حجم بالا اطلاعات نیست.

فرمت 7Z و RAR هم شرایط شان خیلی مانند ZIP است ولی امکان رمزنگاری نام فایلها را هم دارد وایراد اول دیگر وجود ندارد.

ولی برای حجم بالا، درحد رمزنگاری هاردی با ترابایت ها اطلاعات و داشتن سرعت و بازدهی و...
نرم افزارهایی مانند TrueCrypt (دیگر پشتیبانی نمیشود) یا نمونه جدید BitLocker خود ویندوز عالی هستند.
BitLocker ویندوز میتواند کل یک درایو را برایتان رمز کند، تنها روش شکستن BitLocker که روی Win7 دیدم مربوط به ذخیره هشی در فایل Hibernate ویندوز است.
که مایکروسافت جهت راحتی کاربر نگاه میداشته.
نمیدانم الان در ویندوز 10 هم این ضعف وجود دارد یا نه ولی هم احتمالا حل شده و هم با یک تنظیم کوچک در ویندوز قابل رفع است.
خودم الان اطلاعاتم را با BitLocker رمز کرده ام به همکاران و دوستان و برادر خودم هم همین را معرفی کردم.

نقل قول نوشته شده توسط: mahdi72
...درحال حاظر قوی ترین و امن ترین الگوریتم رمزگزاری چی هستش؟

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

در خصوص الگوریتم های هش یکطرفه الآن SHA512 داریم که نسخه جدیدتری از SHA256 و SHA384 است.
البته بسیاری از ابزار و برنامه ها بتازگی بجای SHA1 از SHA256 استفاده میکنند

درخصوص الگوریتم های متقارن (Symmetric) الگوریتم Rijndael و انشعاب آن AES را داریم
(اینها نسل جدیدی از DES است و بلوک های رمزنگاری آن چهار برابر شده اند)

درخصوص الگوریتم های نامتقارن (Asymmetric) هم که نام RSA میدرخشد !
این الگوریتم را میتوان با طول کلیدهای عمومی وخصوصی متفاوتی استفاده نمود، بی نظیر است والبته بسیار کند!
ولی باید دقت کنید که دیگر کاربر نمی تواند خودش گذرواژه ای تایپ کند و به شما بدهد...
دو سری کلیدهای این الگوریتم یک سری اطلاعات باینری 1024 بیتی به بالا هستند که دیگر در حد یک "کلمه" نیستند، مثلا باید در فایلی نگه داری شوند.


- - - - - - - - - - - - - - - - - - - -

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

در اغلب نرم افزارها از یک الگوریتم متقارن (مانند AES) با یک گذرواژه Random برای رمزنگاری اطلاعات استفاده می شود.
سپس این گذرواژه Random تولید شده با RSA رمزنگاری میشود.
*** باید با دقت بیشتری دو خط فوق را بخوانید و به آن فکر کنید ***

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

یا در خود مفاهیم امضای دیجیتال RSA مجدد از یک الگوریتم هش معمولی (مانند SHA1 یا SHA256) هم استفاده میشود.

- - - - - - - - - - - - - - - - - - - -

البته مجدد تاکید میکنم که همین فرمت های عادی Zip و 7Zip و Rar هم از همین الگوریتم ها استفاده کرده و بسیار ایمن هستند، (درواقع از همین الگوریتم ها استفاده میکنند) تنها حمله شناخته شده برای الگوریتم های فعلی همان brute-force و dictionary و... است که همگی براساس امتحان مدام گذرواژه های مختلف است.
در این تصویر شما میتوانید رابطه بین طول گذرواژه و زمان لازم جهت کشف گذرواژه را مشاهده کنید:



موفق باشید.