رمزنگاری در پایتون – راهنمای سریع از صفر تا صد
در این مطلب به موضوع رمزنگاری در پایتون پرداخته شده است و در قالب راهنمایی سریع اما جامع و کاربردی سعی کردهایم تا حد امکان اکثر مباحث پیرامون رمزنگاری در پایتون را پوشش دهیم. در این نوشتار به آموزش انواع روشها و الگوریتمهای رمزنگاری در پایتون به ویژه رمزنگاری سزار در پایتون، رمزنگاری نامتقارن در پایتون و همچنین متقارن، رمزنگاری فایل در پایتون و بسیاری از موارد دیگر پرداخته شده است.
پیش نیازهای رمزنگاری در پایتون
پیش از پرداختن به رمزنگاری در پایتون بهتر است ابتدا برخی از اصول و مبانی رمزنگاری یا همان Cryptography را به طور خلاصه و به بیان ساده شرح دهیم.
رمزنگاری چیست ؟
هنر برقراری ارتباط میان ۲ کاربر از طریق پیامهای «کُدگذاری شده» (Encrypted) را «رمزنگاری» (Cryptography) میگویند. علم رمزنگاری با انگیزه اساسی فراهمسازی امنیت برای پیامهای محرمانه منتقل شده از یک طرف به طرف دیگر پدید آمده است. رمزنگاری به عنوان هنر و علم مخفی کردن پیام برای ارائه حریم خصوصی و محرمانگی در حوزه «امنیت اطلاعات» شناخته میشود.
اصطلاحات رایج رمزنگاری
در این بخش به طور خلاصه مهمترین واژهها و اصطلاحات رایج رمزنگاری را معرفی کردهایم و هر یک را کوتاه شرح دادهایم.
- «متن اصلی» (Plain Text): پیام متنی اصلی به متنی گفته میشود که قابل خواندن است و تمام کاربران میتوانند آن را بخوانند و درک کنند. در واقع متن اصلی همان پیام یا قطعه متنی است که تحت رمزنگاری قرار میگیرد و عملیات رمزگذاری و رمزگشایی روی آن انجام میشود.
- «متن رمزدار» (Cipher Text): پیام یا متنی است که پس از اعمال رمزنگاری روی متن اصلی بدست میآید.
- «رمزگذاری» (Encryption): فرایند تبدیل متن اصلی به متن دارای رمز را رمزگذاری میگویند. همچنین به رمزگذاری «Encoding» (کُدگذاری) هم میگویند.
- «رمزگشایی» (Decryption): به فرایند تبدیل متن رمزدار به متن اصلی نیز رمزگشایی یا «Decoding» (کدگشایی) میگویند.
در نمودار ارائه شده زیر، تمام مراحل رمزنگاری به صورت بصری نمایش داده شده است.
خصوصیت های رمزنگاری مُدرن چه هستند؟
خصوصیتهای اساسی رمزنگاری مُدرن و امروزی به شرح زیر هستند.
- رمزنگاری امروزی بر مبنای دنبالههای بیتی عمل میکنند.
- در رمزنگاری مدرن از الگوریتمهای ریاضیاتی برای برقراری امنیت اطلاعات استفاده میشود.
- رمزنگاری امروزی نیازمند دو طرفِ علاقهمند به برقراری ارتباط از طریق کانال ارتباطی ایمن برای دستیابی به حریم خصوصی است.
کدگذاری با قدرت دو برابری چیست؟
«کدگذاری با قدرت دو برابری» (Double Strength Encryption) که با عنوان «کدگذاری چندگانه» (Multiple Encryption) هم شناخته میشود، فرایند کدگذاری متنی است که بیش از این یک بار با همان الگوریتم قبلی یا با الگوریتمی متفاوت کدگذاری شده است.
به کدگذاری با قدرت دو برابری، «رمزگذاری آبشاری» (Cascade Encryption) و «رمزدار کردن آبشاری» (Cascade Ciphering) هم میگویند.
سطح های مختلف رمزگذاری با قدرت دو برابری کدامند؟
رمزگذاری دو برابری شامل لایههای مختلفی از رمزگذاری میشود که در ادامه شرح داده شدهاند.
- اولین لایه رمزگذاری: متن رمزدار شده از پیام اصلی قابل خواندن با استفاده از الگوریتمهای «درهمسازی» (Hash) و «کلیدهای متقارن» (Symmetric Key) تولید میشود. سپس، کلیدهای متقارن به کمک «کلیدهای نامتقارن» (Asymmetric Keys) رمزگذاری میشوند. بهترین تصویرسازی برای این الگو به صورت زیر است:
- ترکیب کردنِ «خلاصه منظم شده درهمسازی متن رمزدار در چارچوبی خاص» (که به اصطلاح «Hash Digest» نامیده میشود)، در قالب یک کپسول
- دومین لایه رمزگذاری: در این لایه، فرایند اضافه کردن یک لایه بیشتر به متن رمزگذاری شده با همان الگوریتم به کار رفته در لایه قبلی یا با استفاده از الگوریتمی دیگر انجام میشود. معمولاً برای این کار از یک کلمه عبور نامتقارن با طول ۳۲ بیت استفاده میشود.
- سومین لایه رمزگذاری: در این فرایند، کپسول رمزگذاری شده از طریق اتصال SSL یا TLS به طرف دیگر ارتباط انتقال داده میشود.
در نمودار زیر، فرایند رمزگذاری دو برابری به صورت تصویری نشان داده شده است.
رمزنگاری ترکیبی چیست؟
«رمزنگاری ترکیبی» (Hybrid Cryptography) فرایند استفاده از چندین «Cipher» (رمز) از انواع مختلف به همراه یکدیگر به وسیله شامل کردن مزایای هر یک از Cipherها است. رویکردی رایج وجود دارد که معمولاً طی آن، تولید کلید محرمانه تصادفی برای یک رمز متقارن انجام میشود و سپس این کلید از طریق رمزنگاری کلید نامتقارن رمزگذاری میشود.
براساس این الگو، خود پیام اصلی با استفاده از رمز متقارن و پس از آن با استفاده از «کلید محرمانه» (Secret Key) رمزگذاری میشود. گیرنده پس از دریافت، پیام را ابتدا با استفاده از «کلید خصوصی» (Private Key) خودش و به وسیله کلید محرمانه رمزگشایی میکند و سپس از کلید مشخص شده برای رمزگشایی پیام استفاده خواهد کرد.
مروری بر پایتون و نصب آن
پایتون زبانی اسکریپتی و منبع آزاد است و سطح بالا، مفسری، تعاملی و شیگرا به حساب میآید. پایتون بهگونهای طراحی شده است که بتواند خوانایی بالایی داشته باشد. درک سینتکس زبان برنامه نویسی پایتون بسیار آسان است و در قواعد نحوی آن به وفور از کلمات کلیدی ملموس به زبان انگلیسی استفاده شده است.
قابلیت ها و ویژگی های زبان برنامه نویسی پایتون
پایتون قابلیتها و ویژگیهای کلیدی و اساسی زیر را فراهم میسازد.
- زبانی مفسری: کدهای پایتون در زمان اجرا با استفاده از مفسر پردازش میشوند. هیچ نیازی به کامپایل کردن یک برنامه پیش از اجرا در پایتون وجود ندارد. پایتون مشابه زبانهای پرل و PHP است.
- شیگرایی در پایتون: زبان پایتون از روشها و الگوهای شیگرایی پیروی میکند. در پایتون پیادهسازی مفهوم کلاس به همراه ویژگیهای متعددی مثل کپسولهسازی و «پُلیمورفیسم» (چندریختی) انجام میشود.
نکات کلیدی در خصوص زبان پایتون
نکات کلیدی مربوط به زبان برنامه نویسی پایتون در ادامه فهرست شدهاند.
- پایتون شامل روشهای برنامه نویسی تابعی، «ساختارمند» (Structured) و برنامه نویسی شیگرا میشود.
- زبان پایتون را میتوان به عنوان یک زبان اسکریپتی (برای نوشتن اسکریپت) مورد استفاده قرار داد.
- پایتون دارای قابلیت بازیافت زباله خودکار است.
- زبان برنامه نویسی پایتون حاوی نوعهای دادهای سطح بالای پویا است و از انواع مختلف بررسی نوع پویا پشتیبانی میکند.
- پایتون قابلیت ادغام با زبان برنامه نویسی C، سیپلاسپلاس و سایر زبانهایی مثل جاوا را هم دارد.
لینک دانلود پایتون از اینجا [+] قابل دسترسی است. فایلهای دانلود پایتون شامل بستههایی برای سیستم عاملهای مختلفی مثل نصب در ویندوز، مک OS و توزیعهای مختلف لینوکس میشوند. پس از دانلود، نصب پایتون انجام و در نهایت میتوان یادگیری پایتون را آغاز کرد.
برای یادگیری پایتون و به خصوص رمزنگاری در پایتون لازم است با سه مفهوم و نوع داده اصلی و مهم در پایتون شامل رشتهها، لیستها، تاپلها و دیکشنری در پایتون آشنایی داشته باشیم که پیش از این مطالبی جداگانه برای هر یک از آنها منتشر شده است و برای یادگیری آنها میتوان از این مطالب استفاده کرد و بهتر است اینجا از تکرار مکررات خودداری کنیم.
بسته های رمزنگاری در پایتون کدامند؟
پایتون شامل بستهای به نام «Cryptography» است که دستورالعملها و مبانی رمزنگاری در آن فراهم شده است. در این بسته از پایتون ۲.۷، پایتون ۳.۴ به بالا و PyPy نسخه ۵.۳ به بالا پشتیبانی میشود. نصب ساده و ابتدایی پکیج Cryptography در پایتون از طریق دستور زیر حاصل میشود.
1pip install cryptography
بستههای مختلفی، هم با دستورالعملهای سطح بالا و هم با رابطهای سطح پایین، برای الگوریتمهای رایج رمزنگاری مثل «رمزهای متقارن» (Symmetric Ciphers)، «چکیده پیام» (Message Digest) و «توابع استخراج کلید» (Key Derivation Functions) وجود دارند. در طول این مطلب آموزشی، از پکیجهای مختلف پایتون برای پیادهسازی الگوریتمهای رمزنگاری استفاده شده است.
رمزنگاری در پایتون با روش رمز معکوس Reverse Cipher
تا اینجا مروری بر پیشنیازهای رمزنگاری در پایتون و نصب آن روی سیستم داشتیم. در این بخش به طور جامع راجع به «رمز معکوس» (Reverse Cipher و کدنویسی آن بحث شده است.
ویژگی های الگوریتم رمز معکوس Reverse Cipher
الگوریتم رمز معکوس دارای قابلیتها و ویژگیهای زیر است.
- رمز معکوس از الگوی معکوس کردن رشتههای متنی در پیام اصلی برای تبدیل آنها به متن رمزدار استفاده میکند.
- فرایند رمزگذاری و رمزگشایی در این الگوریتم یکسان است.
- برای رمزگشایی متن رمزدار، تنها لازم است کاربر متن رمزدار را معکوس کند تا به متن اصلی برسد.
نقطه ضعف روش رمز معکوس چیست؟
ضعیف بودن روش رمز معکوس بزرگترین عیب آن به حساب میآید. هر هکری میتواند به راحتی متن رمزدار را بشکند و به متن اصلی و اطلاعات رمزگذاری شده دست پیدا کند. بنابراین، روش رمز معکوس گزینه مناسبی برای استفاده در یک کانال ارتباطی ایمن به حساب نمیآید.
مثالی برای روش رمز معکوس
مثالی را در نظر بگیرید که در آن قرار است عبارت «This is program to explain reverse cipher» را با استفاده از روش رمز معکوس رمزگذاری کنیم. در کدهای پایتون زیر از این الگوریتم برای بدست آوردن خروجی استفاده شده است.
1message = 'This is program to explain reverse cipher.'
2translated = '' #cipher text is stored in this variable
3i = len(message) - 1
4
5while i >= 0:
6 translated = translated + message[i]
7 i = i - 1
8print(“The cipher text is : “, translated)
خروجی مثال رمزگذاری معکوس
در تصویر زیر که مربوط به خروجی کدهای بالا است، میتوان متن معکوس شده را مشاهده کرد.
در ادامه توضیحات لازم در خصوص این مثال ارائه شده است.
- متن اصلی در متغیرmessageذخیره شده است و متغیر ترجمه شده نیز برای ذخیرهسازی متن رمزدار ساخته شده مورد استفاده قرار میگیرد.
- طول متن اصلی با استفاده از حلقه for در پایتون و به کمک شماره اندیس محاسبه شده است. کاراکترها در متغیر مربوط به متن رمزدار شده، یعنیtranslated ذخیره میشوند که در خط آخر آن محتوای این متغیر چاپ شده است.
آموزش رمزنگاری سزار در پایتون Caesar Cipher
در بخش قبل به «رمز معکوس» پرداختیم، حال در این بخش میخواهیم روش «رمزنگاری سزار در پایتون» (Caesar Cipher) را با جزئیات کافی شرح دهیم.
ویژگی های الگوریتم رمزنگاری سزار در پایتون
الگوریتم رمزگذاری سزار دارای ویژگیهای زیر است.
- روش رمزگذاری سزار روش رمزگذاری ساده و آسان است.
- این روش نوی ساده از روی «رمز جایگزین» (Substitution Cipher) به حساب میآید.
- هر حرف الفبای اصلی با حرفی جایگزین میشود که با تعداد ثابتی در ترتیب حروف الفبا پایینتر از آن حرف قرار دارد.
در نمودار زیر نحوه عملکرد و پیادهسازی الگوریتم رمزگذاری سزار به تصویر کشیده شده است.
پیادهسازی الگوریتم رمزنگاری سزار در پایتون
در برنامه زیر پیادهسازی الگوریتم رمز سزار انجام شده است.
1def encrypt(text,s):
2result = ""
3 # transverse the plain text
4 for i in range(len(text)):
5 char = text[i]
6 # Encrypt uppercase characters in plain text
7
8 if (char.isupper()):
9 result += chr((ord(char) + s-65) % 26 + 65)
10 # Encrypt lowercase characters in plain text
11 else:
12 result += chr((ord(char) + s - 97) % 26 + 97)
13 return result
14#check the above function
15text = "CEASER CIPHER DEMO"
16s = 4
17
18print "Plain Text : " + text
19print "Shift pattern : " + str(s)
20print "Cipher: " + encrypt(text,s)
خروجی کدهای پیادهسازی الگوریتم رمز سزار
خروجی رمز سزار در تصویر زیر آمده است.
توضیحات لازم در خصوص این مثال در ادامه ارائه شده است.
- برای هر کاراکتر در متن اصلی مربوطه، تبدیل کاراکتر مورد نظر براساس قانون مورد استفاده، بسته به روال رمزگذاری و رمزگشایی متن انجام میشود.
- پس از آنکه گامهای مربوطه دنبال شدند، رشته جدیدی تولید میشود که به آن «متن رمزدار» (Cipher Text) میگویند.
هک کردن الگوریتم رمزنگاری سزار در پایتون چگونه انجام می شود؟
متن رمزدار را میتوان با روشهای مختلفی هک کرد. یکی از این روشها استفاده از تکنیک «Brute Force» (حمله جستجوی فراگیر) است. در این روش، تمام کلیدهای رمزگشایی ممکن امتحان میشود. این روش چندان نیاز به سعی و تلاش زیادی ندارد و به طور نسبی برای یک هکر روش آسانی به حساب میآید. برنامه مربوط به پیادهسازی هک الگوریتم رمز سزار در ادامه آمده است.
1message = 'GIEWIVrGMTLIVrHIQS' #encrypted message
2LETTERS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
3
4for key in range(len(LETTERS)):
5 translated = ''
6 for symbol in message:
7 if symbol in LETTERS:
8 num = LETTERS.find(symbol)
9 num = num - key
10 if num < 0:
11 num = num + len(LETTERS)
12 translated = translated + LETTERS[num]
13 else:
14 translated = translated + symbol
15print('Hacking key #%s: %s' % (key, translated))
متن رمزگذاری شده را در مثال قبلی در نظر بگیرید؛ حال خروجی مربوط به هک کردن به روش بروت فورس و به وسیله تست کردن همه کلیدهای ممکن تا رسیدن به کلید درست در ادامه آمده است.
رمزنگاری در پایتون با الگوریتم ROT13
تا اینجا الگوریتمهای «رمز معکوس» و «رمز سزار» را یاد گرفتهایم. در این بخش الگوریتم ROT13 و نحوه پیادهسازی آن را شرح دادهایم.
شرح الگوریتم ROT13 برای رمزنگاری با پایتون
رمز ROT13 مخفف عبارت «Rotate by 13 places» به معنی «چرخش ۱۳ خانهای» است. این الگوریتم نوع خاصی از رمز سزار است که در آن نقل مکان همیشه با ۱۳ گام انجام میشود. یعنی برای رمزگذاری و رمزگشایی پیام، هر حرف الفبا ۱۳ خانه به جلو انتقال داده میشود.
مثال الگوریتم ROT13
در نمودار زیر فرایند الگوریتم ROT13 به صورت تصویری نشان داده شده است.
پیادهسازی الگوریتم ROT13 با پایتون
برنامه مربوط به پیادهسازی الگوریتم رمزنگاری ROT13 با پایتون در ادامه آمده است.
1from string import maketrans
2
3rot13trans = maketrans('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz',
4 'NOPQRSTUVWXYZABCDEFGHIJKLMnopqrstuvwxyzabcdefghijklm')
5
6# Function to translate plain text
7def rot13(text):
8 return text.translate(rot13trans)
9def main():
10 txt = "ROT13 Algorithm"
11 print rot13(txt)
12
13if __name__ == "__main__":
14 main()
خروجی پیادهسازی الگوریتم ROT13 در تصویر زیر ملاحظه میشود.
نقطه ضعف الگوریتم ROT13 چیست؟
در الگوریتم ROT13 از انتقال ۱۳ خانهای استفاده میشود. بنابراین، حرکت دادن معکوس هر کاراکتر به اندازه ۱۳ خانه کار آسانی است و به راحتی میتوان با این کار متن رمزدار را رمزگشایی کرد.
تجزیه و تحلیل الگوریتم ROT13
الگوریتم رمز ROT13 به عنوان نوع خاصی از الگوریتم رمز سزار محسوب میشود. این الگوریتم چندان ایمن نیست و میتوان آن را به وسیله تجزیه و تحلیل فرکانس یا تنها با امتحان کردن ۲۵ کلید ممکن شکست، چون ROT13 را میتوان تنها با شیفت دادن ۱۳ خانه رمزگشایی کرد. بنابراین، استفاده از این روش چندان کاربردی و عملی نیست.
معرفی فیلم های آموزش برنامه نویسی پایتون
در پلتفرم فرادرس دورههای آموزشی بسیاری برای یادگیری پایتون وجود دارد که تقریباً تمام آنها در صفحهای به نام «مجموعه آموزشهای برنامه نویسی پایتون» گردآوری شدهاند. با توجه به همهمنظوره بودن پایتون و کاربردهای گسترده آن در حوزههای مختلف، دورههای این مجموعه آموزشی هم بسیار متنوع هستند و برای کاربردهای مختلف پایتون در هر یک از این دورهها آموزشهای متنوع و متعددی ارائه شده است. در تصویر فوق تنها تعداد کمی از دورههای این مجموعه به عنوان نمونه آمده است.
- برای مشاهده همه فیلم های آموزش پایتون و شروع یادگیری + اینجا کلیک کنید.
رمز انتقال یافته Transposition Cipher در پایتون
روش «Transposition Cipher» (رمز جابجایی | رمز انتقال یافته) یک الگوریتم رمزنگاری است که در آن ترتیب حروف الفبا در متن اصلی تنظیم مجدد میشود تا متن رمزدار شده حاصل شود. در این فرایند، حروف الفبای اصلی لحاظ نخواهند شد.
مثال الگوریتم رمزنگاری انتقال در پایتون
مثالی ساده برای روش Transposition Cipher، استفاده از روش «رمز انتقال یافته ستونی» (Columnar Transposition Cipher) است که در آن هر کاراکتر مربوط به متن اصلی به صورت افقی با عرض مشخص شده نوشته میشود. سپس رمز مربوطه با نگاه به متن اصلی از جنبه عمودی بدست میآید و در نهایت متن رمزدار شده کاملاً متفاوتی ایجاد میشود.
برای مثال، متن اصلی «hello world» را در نظر بگیرید و بیایید روش ساده تبدیل ستونی را انجام دهیم. همانطور که در ادامه نشان داده شده است، متن اصلی را به صورت افقی نوشته شده در جدول زیر در نظر میگیریم.
ملاحظه میشود که در جدول بالا کاراکترهای متن اصلی به صورت افقی قرار داده شدهاند و متن رمزدار شده با استخراج متن تولیدی با نگاه از جنبه عمودی در جدول فوق بدست میآید که در این مثال به صورت «holewdlo lr» است. حالا دریافت کننده پیام هم باید از همین جدول برای رمزگشایی متن رمزدار شده و تبدیل آن به متن اصلی استفاده کند.
کدهای مثال رمزنگاری Transposition Cipher ستونی در پایتون
کدهای برنامه زیر مربوط به پیادهسازی ساده رمز انتقالی ستونی هستند.
1def split_len(seq, length):
2 return [seq[i:i + length] for i in range(0, len(seq), length)]
3def encode(key, plaintext):
4 order = {
5 int(val): num for num, val in enumerate(key)
6 }
7ciphertext = ''
8
9for index in sorted(order.keys()):
10 for part in split_len(plaintext, len(key)):
11 try:ciphertext += part[order[index]]
12 except IndexError:
13 continue
14 return ciphertext
15print(encode('3214', 'HELLO'))
در ادامه توضیحاتی پیرامون کدهای بالا ارائه شده است.
- با استفاده از تابعsplit_len() میتوانیم کاراکترهای متن اصلی را جداسازی کنیم تا بتوانیم آنها را به صورت ستونی یا سطری قرار بدهیم.
- متُدencode به ایجاد متن رمزدار شده با کلید مشخص کننده تعداد ستونها کمک میکند.
خروجی مثال رمزنگاری با رمز انتقالی ستونی در پایتون
کدهای برنامه برای پیادهسازی ابتدایی روش انتقال ستونی خروجی زیر را تولید میکنند.
عملیات رمزگذاری در روش رمز انتقال یافته
در بخش قبلی، راجع به رمز انتقال یافته یا «Transposition Cipher» توضیحاتی ارائه شد. حال در این بخش به نحوه رمزگذاری در این روش پرداخته شده است.
افزونه Pyperclip در پایتون
کاربرد اصلی افزونه یا همان اکستنشن Pyperclip در زبان برنامه نویسی پایتون این است که بتوانیم ماژولی چندپلتفرمی برای کپی و پیست کردن متن در کلیپبُرد را داشته باشیم. ميتوان ماژول pyperclip را به وسیله وارد کردن دستور زیر در پایتون نصب کرد.
1pip install pyperclip
اگر نیازمندیهای مربوطه همین حالا هم در سیستم موجود باشند، خروجی در خط فرمان به صورت زیر خواهد بود.
پیادهسازی عملیات رمزگذاری به روش رمز انتقال یافته در پایتون
کدهای پایتون مربوط به رمزگذاری به روش انتقالی که در آنها pyperclip ماژول اصلی به حساب میآید در ادامه آمده است.
1import pyperclip
2def main():
3 myMessage = 'Transposition Cipher'
4 myKey = 10
5 ciphertext = encryptMessage(myKey, myMessage)
6
7 print("Cipher Text is")
8 print(ciphertext + '|')
9 pyperclip.copy(ciphertext)
10
11def encryptMessage(key, message):
12 ciphertext = [''] * key
13
14 for col in range(key):
15 position = col
16 while position < len(message):
17 ciphertext[col] += message[position]
18 position += key
19 return ''.join(ciphertext) #Cipher text
20if __name__ == '__main__':
21 main()
خروجی کدهای مثال پیادهسازی رمزگذاری به روش رمز انتقال یافته در پایتون به صورت زیر است.
توضیحات کدهای بالا در ادامه ارائه شده است.
- تابعmain() متدencryptMessage() را فراخوانی میکند. این متُد شامل روال مربوط به بخشبندی کاراکترها با استفاده از تابعlenو پیمایش این کاراکترها به صورت ستونی میشود.
- تابعmain() در انتها نمونهسازی اولیه میشود تا خروجی مطلوب را دریافت کنیم.
رمزگشایی در روش رمز انتقال یافته
در این بخش، روال رمزگشایی را در الگوریتم رمز انتقالی خواهیم آموخت.
کدهای پیادهسازی رمزگشایی در روش رمز انتقال یافته با پایتون
برای درک بهتر نحوه پیادهسازی عملیات رمزگشایی الگوریتم رمز انتقالی در پایتون به کدهای زیر توجه کنید. متن رمزدار برای پیامی با محتوای «Transposition Cipher» با مقدار کلید «۶» به صورت «Toners raiCntisippoh» خواهد بود.
1import math, pyperclip
2def main():
3 myMessage= 'Toners raiCntisippoh'
4 myKey = 6
5 plaintext = decryptMessage(myKey, myMessage)
6
7 print("The plain text is")
8 print('Transposition Cipher')
9
10def decryptMessage(key, message):
11 numOfColumns = math.ceil(len(message) / key)
12 numOfRows = key
13 numOfShadedBoxes = (numOfColumns * numOfRows) - len(message)
14 plaintext = float('') * numOfColumns
15 col = 0
16 row = 0
17
18 for symbol in message:
19 plaintext[col] += symbol
20 col += 1
21 if (col == numOfColumns) or (col == numOfColumns - 1 and row >= numOfRows - numOfShadedBoxes):
22 col = 0 row += 1 return ''.join(plaintext)
23if __name__ == '__main__':
24 main()
توضیحات کدهای پیادهسازی رمزگشایی الگوریتم رمز انتقال یافته
متن رمزدار شده و کلیدهای مربوطه، دو مقداری هستند که به عنوان پارامترهای ورودی برای کدگشایی یا همان رمزگشایی متن رمزدار به صورت معکوس به وسیله قرار دادن کاراکترها در قالب ستونی و خواندن آنها به صورت افقی استفاده میشود. ميتوان حروف الفبا را در قالبی ستونی قرار داد و بعداً آنها را به وسیله کدهای زیر با هم ترکیب یا ادغام کرد.
1for symbol in message:
2 plaintext[col] += symbol
3 col += 1
4
5 if (col == numOfColumns) or (col == numOfColumns - 1 and row >= numOfRows - numOfShadedBoxes):
6 col = 0
7 row += 1
8return ''.join(plaintext)
خروجی کدهای رمزگشایی الگوریتم رمز انتقال یافته
کدهای برنامه برای رمزگشایی الگوریتم Transposition Cipher به صورت زیر است.
آموزش رمزگشایی و رمزنگاری فایل در پایتون
در پایتون امکان رمزگذاری و رمزگشایی فایلها قبل از انتقال به کانال ارتباطی وجود دارد. برای انجام این کار، لازم است از افزونه PyCrypto در پایتون استفاده کنیم. میتوان این پلاگین را با استفاده از دستور زیر در پایتون نصب کرد.
1pip install pycrypto
اگر این افزونه یا همان پلاگین از قبل نصب شده باشد، خروجی پس از وارد کردن دستور بالا در خط فرمان به صورت زیر خواهد بود.
کدهای پیادهسازی رمزگشایی و رمزنگاری فایل ها با پایتون
کدهای برنامه مربوط به رمزگذاری فایل به امکان محافظت با کلمه عبور در ادامه آمده است.
1# =================Other Configuration================
2# Usages :
3usage = "usage: %prog [options] "
4# Version
5Version="%prog 0.0.1"
6# ====================================================
7# Import Modules
8import optparse, sys,os
9from toolkit import processor as ps
10def main():
11 parser = optparse.OptionParser(usage = usage,version = Version)
12 parser.add_option(
13 '-i','--input',type = 'string',dest = 'inputfile',
14 help = "File Input Path For Encryption", default = None)
15
16 parser.add_option(
17 '-o','--output',type = "string",dest = 'outputfile',
18 help = "File Output Path For Saving Encrypter Cipher",default = ".")
19
20 parser.add_option(
21 '-p','--password',type = "string",dest = 'password',
22 help = "Provide Password For Encrypting File",default = None)
23
24 parser.add_option(
25 '-p','--password',type = "string",dest = 'password',
26 help = "Provide Password For Encrypting File",default = None)
27
28 (options, args)= parser.parse_args()
29
30 # Input Conditions Checkings
31 if not options.inputfile or not os.path.isfile(options.inputfile):
32 print " [Error] Please Specify Input File Path"
33 exit(0)
34 if not options.outputfile or not os.path.isdir(options.outputfile):
35 print " [Error] Please Specify Output Path"
36 exit(0)
37 if not options.password:
38 print " [Error] No Password Input"
39 exit(0)
40 inputfile = options.inputfile
41
42 outputfile = os.path.join(
43 options.outputfile,os.path.basename(options.inputfile).split('.')[0]+'.ssb')
44 password = options.password
45 base = os.path.basename(inputfile).split('.')[1]
46 work = "E"
47
48 ps.FileCipher(inputfile,outputfile,password,work)
49 return
50
51 if __name__ == '__main__':
52 main()
برای اجرای فرایند رمزگذاری با کلمه عبور، لازم است دستور زیر را در خط فرمان پایتون وارد کنیم.
1python pyfilecipher-encrypt.py -i file_path_for_encryption -o output_path -p password
با اجرای خط کُد بالا، خروجی زیر در خط فرمان نشان داده خواهد شد.
توضیحات کدهای رمزگذاری فایل با پایتون
کلمههای عبور با استفاده از الگوریتم درهمسازی MD5 تولید شدهاند و مقادیر در فایلهای پشتیبانگیری شده ساده و ایمن در سیستم ویندوز ذخیره شدهاند. این کلمههای عبور شامل مقادیر زیر میشوند.
رمزگشایی فایل ها در پایتون
در این بخش به رمزگشایی یا کُدگشایی فایلها در حوزه رمزنگاری در پایتون میپردازیم. باید توجه شود که برای فرایند رمزگشایی، از روال و مراحل یکسانی پیروی میکنیم، اما به جای مشخص کردن مسیر خروجی، روی مسیر ورودی یا فایل مربوطه که رمزگذاری شده تمرکز خواهیم داشت.
کدهای رمزگشایی فایل در پایتون
در ادامه کدهای نمونه برای رمزگشایی فایلها در رمزنگاری با پایتون ارائه شده است.
1#!/usr/bin/python
2# ---------------- READ ME ---------------------------------------------
3# This Script is Created Only For Practise And Educational Purpose Only
4# This Script Is Created For http://bitforestinfo.blogspot.in
5# This Script is Written By
6#
7#
8##################################################
9######## Please Don't Remove Author Name #########
10############### Thanks ###########################
11##################################################
12#
13#
14# =================Other Configuration================
15# Usages :
16usage = "usage: %prog [options] "
17# Version
18Version="%prog 0.0.1"
19# ====================================================
20# Import Modules
21import optparse, sys,os
22from toolkit import processor as ps
23def main():
24 parser = optparse.OptionParser(usage = usage,version = Version)
25 parser.add_option(
26 '-i','--input',type = 'string',dest = 'inputfile',
27 help = "File Input Path For Encryption", default = None)
28
29 parser.add_option(
30 '-o','--output',type = "string",dest = 'outputfile',
31 help = "File Output Path For Saving Encrypter Cipher",default = ".")
32
33 parser.add_option(
34 '-p','--password',type = "string",dest = 'password',
35 help = "Provide Password For Encrypting File",default = None)
36 (options, args) = parser.parse_args()
37 # Input Conditions Checkings
38 if not options.inputfile or not os.path.isfile(options.inputfile):
39 print " [Error] Please Specify Input File Path"
40 exit(0)
41 if not options.outputfile or not os.path.isdir(options.outputfile):
42 print " [Error] Please Specify Output Path"
43 exit(0)
44 if not options.password:
45 print " [Error] No
46 exit(0)
47 inputfile = options.inputfile
48 outputfile = options.outputfile
49 password = options.password
50 work = "D"
51 ps.FileCipher(inputfile,outputfile,password,work)
52 return
53if __name__ == '__main__':
54 main()
میتوان دستور زیر را برای اجرای کدهای بالا مورد استفاده قرار داد.
1python pyfilecipher-decrypt.py -i encrypted_file_path -p password
خروجی کدهای فوق به صورت زیر است.
- نکته: خروجی بالا، مقادیر درهمسازی را پیش از رمزگذاری و پس از رمزگشایی مشخص میکند. بنابراین مشخص میشود که همان فایل مورد نظر رمزگذاری و فرایند مربوطه با موفقیت انجام شده است.
رمزگذاری و رمزگشایی Base64 در پایتون
در رمزگذاری Base64 دادههای دودویی به قالب آن متنی تبدیل میشوند که از طریق کانال ارتباطی منتقل میشود و در این کانال کاربر میتواند تبادل متنی به صورت ایمن داشته باشد. همچنین Base64 را «Privacy Enhanced Electronic Mail» هم مینامند که به اختصار PEM خطاب میشود و در اصل برای فرایند رمزگذاری ایمیل مورد استفاده قرار میگیرد.
پایتون دارای ماژولی به نام BASE64 است که در آن دو تابع اصلی وجود دارد. این دو تابع در ادامه معرفی شدهاند.
- base64.decode(input, output) : این تابع مقدار پارامتر ورودی تعیین شده را کدگشایی میکند و خروجی کدگشایی شده را به عنوان یک شی ذخیره میکند.
- Base64.encode(input, output) : این تابع مقدار پارامتر ورودی مشخص شده را کدگذاری و خروجی کدگذاری شده را به عنوان یک شی ذخیره میکند.
برنامه کدگذاری Base64 در پایتون
برای اجرای کدگذاری base64 میتوان از قطعه کد زیر استفاده کرد.
1import base64
2encoded_data = base64.b64encode("Encode this text")
3
4print("Encoded text with base 64 is")
5print(encoded_data)
با اجرای کدهای بالا برای کدگذاری base64 خروجی زیر حاصل میشود.
برنامه کدگشایی Base64 در پایتون
میتوان از قطعه کد زیر برای اجرای کدگشایی با روش base64 استفاده کرد.
1import base64
2decoded_data = base64.b64decode("RW5jb2RlIHRoaXMgdGV4dA==")
3
4print("decoded text is ")
5print(decoded_data)
خروجی کدهای مربوط به کدگشایی به روش base64 به صورت زیر است.
تفاوت ASCII و base64 چیست ؟
تفاوتهای کار با ASCII و base64 برای کدگذاری دادهها شامل موارد زیر میشود.
- وقتی متنها را با استفاده از ASCII کدگذاری میکنیم، کار با یک رشته متنی آغاز میشود و سپس آن را به دنبالهای از بایتها تبدیل میکنیم.
- وقتی دادهها را با استفاده از روش base64 کدگذاری میکنیم، کار با دنبالهای از بایتها شروع میشود و بعد آن را به رشتهای متنی تبدیل میکنیم.
نقطه ضعف الگوریتم Base64 چیست ؟
الگوریتم Base64 معمولاً برای ذخیرهسازی کلمههای عبور در پایگاه داده استفاده میشود. نقطه ضعف اصلی آن این است که هر کلمه کدگذاری شده میتواند به راحتی از طریق هر ابزار آنلاینی کدگشایی شود و متجاوزان میتوانند به راحتی اطلاعات را در اختیار بگیرند.
رمزنگاری در پایتون با فرایند XOR
در این بخش، فرایند XOR شرح داده شده و کدهای پایتون مربوط به آن هم آمده است.
الگوریتم رمزنگاری در پایتون با فرایند XOR
الگوریتم کدگذاری و کدگشایی XOR متن اصلی را به قالب بایتهای ASCII تبدیل میکند و از روش XOR برای تبدیل آن به یک بایت تعیین شده استفاده میکند. این روش مزیتهای زیر را برای کاربران آن فراهم میسازد.
- این روش سرعت محاسباتی بالایی دارد.
- هیچ تفاوتی در سمت چپ و سمت راست علامتگذاری نمیشود.
- درک و تجزیه تحلیل آن آسان است.
کدهای الگوریتم رمزنگاری در پایتون با فرایند XOR
برای اجرای فرایند XOR میتوانید از کدهای زیر استفاده کنید.
1def xor_crypt_string(data, key = 'awesomepassword', encode = False, decode = False):
2 from itertools import izip, cycle
3 import base64
4
5 if decode:
6 data = base64.decodestring(data)
7 xored = ''.join(chr(ord(x) ^ ord(y)) for (x,y) in izip(data, cycle(key)))
8
9 if encode:
10 return base64.encodestring(xored).strip()
11 return xored
12secret_data = "XOR procedure"
13
14print("The cipher text is")
15print xor_crypt_string(secret_data, encode = True)
16print("The plain text fetched")
17print xor_crypt_string(xor_crypt_string(secret_data, encode = True), decode = True)
خروجی کدهای الگوریتم رمزنگاری در پایتون با فرایند XOR
کدهای مربوط به فرایند XOR خروجی زیر را در پی خواهد داشت.
توضیح کدهای رمزنگاری با فرایند XOR در پایتون
توضیحات لازم در خصوص کدهای بالا در ادامه آمده است.
- تابعxor_crypt_string() شامل پارامتری برای مشخص کردن نوع کدگذاری و کدگشایی و همچنین مقدار رشته میشود.
- توابع اساسی با ماژولهای base64 به کار رفتهاند که روش و عملیات XOR را برای کدگذاری یا کدگشایی متن اصلی یا متن رمزدار دنبال میکنند.
نکته: کدگذاری به روش XOR برای رمزگذاری دادهها استفاده میشود و رخنه به آن با استفاده از روش بروت فورس دشوار است. در روش بروت فورس کلیدهای رمزگذاری تصادفی تولید میشوند تا در نهایت یکی از آنها با متن رمزدار مطابقت داشته باشد و به این ترتیب رمز شکسته شود.
رمز ضربی Multiplicative Cipher با پایتون
حین استفاده از روش رمزگذاری سزار، نمادهای رمزگذاری و رمزگشایی شامل تبدیل مقادیر به اعداد با استفاده از یک روش ساده و ابتدایی جمع یا تفریق میشود. اگر برای تبدیل متن رمزدار از عملیات ضرب استفاده شود، به آن «وضعیت دورپیچ» (wrap-around) میگویند. حروف الفبا و اعداد متناظر با آن را مطابق تصویر زیر در نظر بگیرید.
در روش Multiplicative Cipher از اعداد برای عملیات ضرب استفاده خواهد شد و کلید متناظر نیز برابر با ۷ است. فرمول اساسی که در چنین سناریویی برای تولید یک رمز ضربی استفاده میشود در ادامه آمده است.
1(Alphabet Number * key)mod(total number of alphabets)
عدد دریافتی از طریق خروجی در جدول بالا نگاشت میشود و حرف الفبای متناظر به عنوان حرف الفبای کدگذاری شده دریافت خواهد شد.
تابع مدولاسیون مربوط به روش Multiplicative Cipher یا همان رمز ضربی در پایتون در ادامه آمده است.
1def unshift(key, ch):
2 offset = ord(ch) - ASC_A
3 return chr(((key[0] * (offset + key[1])) % WIDTH) + ASC_A)
- نکته: مزیتی که روش رمز ضربی دارد این است که میتوان در آن از کلیدهایی بسیار بزرگ مثل 8953851 استفاده کرد. به همین دلیل مثلاً برای این کلید زمان بسیار زیادی نیاز است تا بتوان با کامپیوتر عملیات بروت فورس را انجام داد و بین ۹ میلیون کلید ممکن مقدار صحیح را بدست آورد.
رمزنگاری در پایتون با Affine Cipher
روش Affine Cipher ترکیبی از الگوریتمهای رمز ضربی و رمز سزار است. پیادهسازی اساسی Affine Cipher در تصویر زیر نمایش داده شده است.
در این بخش، پیادهسازی الگوریتم Affine Cipher را به وسیله ایجاد کلاس متناظر با آن انجام دادهایم. کلاس مربوطه شامل دو تابع اساسی برای رمزگذاری و رمزگشایی میشود.
کدهای رمزنگاری Affine Cipher با پایتون
برای پیادهسازی Affine Cipher میتوانید از کدهای زیر استفاده کنید.
1class Affine(object):
2 DIE = 128
3 KEY = (7, 3, 55)
4 def __init__(self):
5 pass
6 def encryptChar(self, char):
7 K1, K2, kI = self.KEY
8 return chr((K1 * ord(char) + K2) % self.DIE)
9
10 def encrypt(self, string):
11 return "".join(map(self.encryptChar, string))
12
13 def decryptChar(self, char):
14 K1, K2, KI = self.KEY
15 return chr(KI * (ord(char) - K2) % self.DIE)
16
17 def decrypt(self, string):
18 return "".join(map(self.decryptChar, string))
19 affine = Affine()
20print affine.encrypt('Affine Cipher')
21print affine.decrypt('*18?FMT')
وقتی روش Affine Cipher را با استفاده از کدهای بالا پیادهسازی کنیم، خروجی زیر را خواهیم داشت.
در خروجی پیام رمزگذاری شده برای پیام متن اصلی «Affine Cipher» چاپ میشود و پیام رمزگشایی شده برای پیام ارسالی به عنوان ورودی هم «abcdefg» است.
رمز تک الفبایی Monoalphabetic Cipher و هک کردن آن در پایتون
در این بخش راجع به «رمز تک الفبایی» (monoalphabetic cipher) و هک کردن آن را با استفاده از پایتون خواهیم آموخت.
رمز تک الفبایی Monoalphabetic Cipher چیست ؟
رمز تک الفبایی از جایگزینی ثابتی برای رمزگذاری کُل پیام استفاده میکند. در ادامه رمز تک الفبایی با استفاده از دیکشنری پایتون با اشیای JSON نشان داده شده است.
1monoalpha_cipher = {
2 'a': 'm',
3 'b': 'n',
4 'c': 'b',
5 'd': 'v',
6 'e': 'c',
7 'f': 'x',
8 'g': 'z',
9 'h': 'a',
10 'i': 's',
11 'j': 'd',
12 'k': 'f',
13 'l': 'g',
14 'm': 'h',
15 'n': 'j',
16 'o': 'k',
17 'p': 'l',
18 'q': 'p',
19 'r': 'o',
20 's': 'i',
21 't': 'u',
22 'u': 'y',
23 'v': 't',
24 'w': 'r',
25 'x': 'e',
26 'y': 'w',
27 'z': 'q',
28 ' ': ' ',
29}
با کمک این دیکشنری، میتوانیم حروف الفبا را با حروف مرتبط با آن به عنوان مقادیر با JSON رمزگذاری کنیم. در کدهای زیر برنامهای تک الفبایی به عنوان نمایشی کلاسگونه ایجاد شده است که شامل تمام توابع رمزگذاری و رمزگشایی میشود.
1from string import letters, digits
2from random import shuffle
3
4def random_monoalpha_cipher(pool = None):
5 if pool is None:
6 pool = letters + digits
7 original_pool = list(pool)
8 shuffled_pool = list(pool)
9 shuffle(shuffled_pool)
10 return dict(zip(original_pool, shuffled_pool))
11
12def inverse_monoalpha_cipher(monoalpha_cipher):
13 inverse_monoalpha = {}
14 for key, value in monoalpha_cipher.iteritems():
15 inverse_monoalpha[value] = key
16 return inverse_monoalpha
17
18def encrypt_with_monoalpha(message, monoalpha_cipher):
19 encrypted_message = []
20 for letter in message:
21 encrypted_message.append(monoalpha_cipher.get(letter, letter))
22 return ''.join(encrypted_message)
23
24def decrypt_with_monoalpha(encrypted_message, monoalpha_cipher):
25 return encrypt_with_monoalpha(
26 encrypted_message,
27 inverse_monoalpha_cipher(monoalpha_cipher)
28 )
این فایل بعداً برای پیادهسازی فرایند رمزگذاری و رمزگشایی به روش تک الفبایی فراخوانی میشود که این پیادهسازی در ادامه آمده است.
1import monoalphabeticCipher as mc
2
3cipher = mc.random_monoalpha_cipher()
4print(cipher)
5encrypted = mc.encrypt_with_monoalpha('Hello all you hackers out there!', cipher)
6decrypted = mc.decrypt_with_monoalpha('sXGGt SGG Nt0 HSrLXFC t0U UHXFX!', cipher)
7
8print(encrypted)
9print(decrypted)
خروجی کدهای پیادهسازی رمز تک الفبایی در پایتون
وقتی کدهای ارائه شده در بالا را پیادهسازی میکنیم، میتوانیم خروجی زیر را مشاهده کنیم.
بنابراین میتوان یک رمز تک الفبایی را با جفت کلید-مقدار تعیین شده هک کرد که این کار باعث میشود متن رمزدار شده به متن اصلی تبدیل شود.
رمزنگاری جایگزینی ساده Simple Substitution Cipher در پایتون
رمزنگاری جایگزینی ساده رایجترین روش رمزدار کردن و رمزنگاری در پایتون به حساب میآید و شامل الگوریتمی برای جایگزینی هر کاراکتر متن اصلی با هر کاراکتر متن رمزدار میشود. در این فرایند در مقایسه با روش رمزنگاری سزار، حروف الفبا مغشوش و به هم ریخته میشوند.
مثالی برای روش رمزنگاری جایگزینی ساده در پایتون
کلیدهای مربوط به رمزنگاری جایگزینی ساده معمولاً شامل ۲۶ حرف میشود. یک کلید نمونه در ادامه آمده است.
plain alphabet : abcdefghijklmnopqrstuvwxyz cipher alphabet: phqgiumeaylnofdxjkrcvstzwb
مثالی از رمزگذاری با استفاده از کلیدهای بالا در ادامه مشاهده میشود.
plaintext : defend the east wall of the castle ciphertext: giuifg cei iprc tpnn du cei qprcni
کدهای زیر مربوط به برنامهای هستند که در آن روش رمزنگاری جایگزینی ساده با پایتون پیادهسازی شده است.
1import random, sys
2
3LETTERS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
4def main():
5 message = ''
6 if len(sys.argv) > 1:
7 with open(sys.argv[1], 'r') as f:
8 message = f.read()
9 else:
10 message = raw_input("Enter your message: ")
11 mode = raw_input("E for Encrypt, D for Decrypt: ")
12 key = ''
13
14 while checkKey(key) is False:
15 key = raw_input("Enter 26 ALPHA key (leave blank for random key): ")
16 if key == '':
17 key = getRandomKey()
18 if checkKey(key) is False:
19 print('There is an error in the key or symbol set.')
20 translated = translateMessage(message, key, mode)
21 print('Using key: %s' % (key))
22
23 if len(sys.argv) > 1:
24 fileOut = 'enc.' + sys.argv[1]
25 with open(fileOut, 'w') as f:
26 f.write(translated)
27 print('Success! File written to: %s' % (fileOut))
28 else: print('Result: ' + translated)
29
30# Store the key into list, sort it, convert back, compare to alphabet.
31def checkKey(key):
32 keyString = ''.join(sorted(list(key)))
33 return keyString == LETTERS
34def translateMessage(message, key, mode):
35 translated = ''
36 charsA = LETTERS
37 charsB = key
38
39 # If decrypt mode is detected, swap A and B
40 if mode == 'D':
41 charsA, charsB = charsB, charsA
42 for symbol in message:
43 if symbol.upper() in charsA:
44 symIndex = charsA.find(symbol.upper())
45 if symbol.isupper():
46 translated += charsB[symIndex].upper()
47 else:
48 translated += charsB[symIndex].lower()
49 else:
50 translated += symbol
51 return translated
52def getRandomKey():
53 randomList = list(LETTERS)
54 random.shuffle(randomList)
55 return ''.join(randomList)
56if __name__ == '__main__':
57 main()
خروجی کدهای فوق در تصویر زیر مشاهده میشود.
تست و ارزیابی روش رمز جایگزینی ساده
در این بخش روی تست کردن رمزنگاری جایگزینی ساده با استفاده از روشهای مختلف تمرکز کردهایم. این روش به ما کمک میکند تا بتوانیم مطابق کدهای زیر رشتههای تصادفی تولید کنیم.
1import random, string, substitution
2def main():
3 for i in range(1000):
4 key = substitution.getRandomKey()
5 message = random_string()
6 print('Test %s: String: "%s.."' % (i + 1, message[:50]))
7 print("Key: " + key)
8 encrypted = substitution.translateMessage(message, key, 'E')
9 decrypted = substitution.translateMessage(encrypted, key, 'D')
10
11 if decrypted != message:
12 print('ERROR: Decrypted: "%s" Key: %s' % (decrypted, key))
13 sys.exit()
14 print('Substutition test passed!')
15
16def random_string(size = 5000, chars = string.ascii_letters + string.digits):
17 return ''.join(random.choice(chars) for _ in range(size))
18if __name__ == '__main__':
19 main()
خروجی در تصویر زیر آمده است که در آن ميتوان رشتههای تولید شده به صورت تصادفی را مشاهده کرد. این کار برای ایجاد تصادفی پیامهای متنی اصلی و بدون رمز انجام میشود.
حالا بعد از آنکه تست و ارزیابی با موفقیت تکمیل شد، میتوان پیام خروجی (یعنی Substitution test passed! را مشاهده کرد).
رمزگشایی Simple Substitution Cipher
در این بخش پیادهسازی ساده رمزنگاری جایگزینی انجام شده است. با استفاده از این کدها پیام رمزگذاری و رمزگشایی شده به ازای هر منطق مورد استفاده در روش رمزنگاری جایگزینی ساده نمایش داد شده است.
کدهای رمزگشایی رمز جایگزینی ساده
برای اجرای رمزگشایی در روش رمزنگاری جایگزینی ساده میتوان از کدهای زیر استفاده کرد.
1import random
2chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' +
3 'abcdefghijklmnopqrstuvwxyz' +
4 '0123456789' +
5 ':.;,?!@#$%&()+=-*/_<> []{}`~^"''
6
7def generate_key():
8 """Generate an key for our cipher"""
9 shuffled = sorted(chars, key=lambda k: random.random())
10 return dict(zip(chars, shuffled))
11
12def encrypt(key, plaintext):
13 """Encrypt the string and return the ciphertext"""
14 return ''.join(key[l] for l in plaintext)
15
16def decrypt(key, ciphertext):
17 """Decrypt the string and return the plaintext"""
18 flipped = {v: k for k, v in key.items()}
19 return ''.join(flipped[l] for l in ciphertext)
20
21def show_result(plaintext):
22 """Generate a resulting cipher with elements shown"""
23 key = generate_key()
24 encrypted = encrypt(key, plaintext)
25 decrypted = decrypt(key, encrypted)
26
27 print 'Key: %s' % key
28 print 'Plaintext: %s' % plaintext
29 print 'Encrypted: %s' % encrypted
30 print 'Decrypted: %s' % decrypted
31show_result('Hello World. This is demo of substitution cipher')
کدهای بالا خروجی زیر را تولید خواهند کرد.
ماژول های رمزنگاری در پایتون کدامند؟
در این بخش ماژولهای مختلف رمزنگاری در پایتون معرفی و توضیحات لازم در خصوص آنها ارائه شده است.
ماژول رمزنگاری Cryptography در پایتون
این ماژول شامل تمام دستورالعملها، اصول و مبانی رمزنگاری در پایتون میشود و واسطی سطح بالا برای کد نویسی در پایتون را فراهم میسازد. میتوان ماژول cryptography را با استفاده از pip به صورت دستور زیر نصب کرد.
1pip install cryptography
با وارد کردن دستور بالا در خط فرمان پایتون، خروجی چیزی مشابه تصویر زیر خواهد بود.
کدهای پیادهسازی ماژول Cryptography در پایتون
برای پیادهسازی ماژول Cryptography در پایتون میتوان از کدهای زیر استفاده کرد.
1from cryptography.fernet import Fernet
2key = Fernet.generate_key()
3cipher_suite = Fernet(key)
4cipher_text = cipher_suite.encrypt("This example is used to demonstrate cryptography module")
5plain_text = cipher_suite.decrypt(cipher_text)
خروجی کدهای فوق در ادامه آمده است.
حالا کدهایی که در ادامه آمده است برای تایید کلمه عبور و درهمسازی آن استفاده میشود. علاوه بر این، این کدها شامل منطق لازم برای تایید کلمه عبور با هدف احراز هویت نیز میشوند.
1import uuid
2import hashlib
3
4def hash_password(password):
5 # uuid is used to generate a random number of the specified password
6 salt = uuid.uuid4().hex
7 return hashlib.sha256(salt.encode() + password.encode()).hexdigest() + ':' + salt
8
9def check_password(hashed_password, user_password):
10 password, salt = hashed_password.split(':')
11 return password == hashlib.sha256(salt.encode() + user_password.encode()).hexdigest()
12
13new_pass = input('Please enter a password: ')
14hashed_password = hash_password(new_pass)
15print('The string to store in the db is: ' + hashed_password)
16old_pass = input('Now please enter the password again to check: ')
17
18if check_password(hashed_password, old_pass):
19 print('You entered the right password')
20else:
21 print('Passwords do not match')
برای خروجی، ۲ سناریو ممکن است اتفاق بیوفتد که در ادامه به هر یک از این ۲ سناریو پرداخته شده است.
- سناریو ۱: اگر کلمه عبور به درستی وارد شده باشد، خروجی به صورت زیر خواهد بود.
- سناریو ۲: اگر کلمه عبور به اشتباه وارد شده باشد، خروجی مشابه تصویر زیر خواهد بود.
رمز ویژنر Vignere Cipher چیست؟
«رمز ویژنر» (Vignere Cipher) با الگوریتم رمز سزار برای رمزگذاری و رمزگشایی ارتباطاتی دارد. رمز ویژنر مشابه رمز سزار عمل میکند، اما تنها یک تمایز اساسی با آن دارد:
رمز سزار شامل الگوریتمی با یک انتقال تک کاراکتری است، در حالی که رمز ویژنر شامل کلیدی با چندین انتقال حروف الفبا میشود.
فرمول ریاضی رمز ویژنر
برای رمزگذاری، فرمول ریاضی الگوریتم رمز ویژنر به صورت زیر است.
برای رمزگشایی فرمول ریاضی در ادامه آمده است.
رمز ویژنر از بیش از یک مجموعه جایگزینی استفاده میکند و به همین دلیل آن را «رمز چند الفبایی» (Polyalphabetic Cipher) هم مینامند. رمز ویژنر از نمایش کلید حرفی به جای کلید عددی استفاده میکند. این رویکرد به این صورت است که حرف «A» برای کلید صفر استفاده خواهد شد، حرف B برای کلید ۱ و تا آخر به همین شکل ادامه دارد. اعداد حرفهای قبل و بعد از فرایند رمزگذاری در ادامه نشان داده شده است.
ترکیبهای ممکن از تعداد کلیدهای ممکن بر اساس طول کلید ويژنر در ادامه آمده است. نتیجه مشخص میکند که الگوریتم رمزنگاری ويژنر چقدر ایمن است.
جدول رمز ویژنر
تصویر جدولی که برای رمز ویژنر استفاده میشود و به آن «Vignere Tableau» میگویند در ادامه آمده است.
پیادهسازی رمزنگاری ویژنر در پایتون
در این بخش به نحوه پیادهسازی رمزنگاری ویژنر در پایتون پرداختهایم. متن نمونه «This is basic implementation of Vignere Cipher» را در نظر بگیرید که قرار است کدگذاری شود و کلیدی هم که برای رمزنگاری استفاده میشود، «PIZZA» خواهد بود. برای پیادهسازی رمز ویژنر در پایتون میتوان از کدهای زیر استفاده کرد.
1import pyperclip
2
3LETTERS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
4def main():
5 myMessage = "This is basic implementation of Vignere Cipher"
6 myKey = 'PIZZA'
7 myMode = 'encrypt'
8
9 if myMode == 'encrypt':
10 translated = encryptMessage(myKey, myMessage)
11 elif myMode == 'decrypt':
12 translated = decryptMessage(myKey, myMessage)
13
14 print('%sed message:' % (myMode.title()))
15 print(translated)
16 print()
17def encryptMessage(key, message):
18 return translateMessage(key, message, 'encrypt')
19def decryptMessage(key, message):
20 return translateMessage(key, message, 'decrypt')
21def translateMessage(key, message, mode):
22 translated = [] # stores the encrypted/decrypted message string
23 keyIndex = 0
24 key = key.upper()
25
26 for symbol in message:
27 num = LETTERS.find(symbol.upper())
28 if num != -1:
29 if mode == 'encrypt':
30 num += LETTERS.find(key[keyIndex])
31 elif mode == 'decrypt':
32 num -= LETTERS.find(key[keyIndex])
33 num %= len(LETTERS)
34
35 if symbol.isupper():
36 translated.append(LETTERS[num])
37 elif symbol.islower():
38 translated.append(LETTERS[num].lower())
39 keyIndex += 1
40
41 if keyIndex == len(key):
42 keyIndex = 0
43 else:
44 translated.append(symbol)
45 return ''.join(translated)
46if __name__ == '__main__':
47 main()
تصویر خروجی کدهای بالا در ادامه آمده است.
بررسی ترکیبهای ممکن برای هک کردن رمز ویژنر تقریباً غیرممکن است و به همین دلیل این روش به عنوان یکی از روشهای ایمن رمزنگاری و رمزگذاری به حساب میآید.
رمزنگاری پد یک بار مصرف One Time Pad Cipher در پایتون
«رمز پد یک بار مصرف» (One Time Pad Cipher) نوعی روش رمزنگاری است که ویژگیهای آن در ادامه فهرست شدهاند.
- این روش رمزنگاری بسیار ایمن و غیر قابل نفوذ به حساب میآید.
- کلید در این روش دقیقاً با طول پیام رمزگذاری شده یکسان است.
- در این روش کلید از نمادهای تصادفی ساخته میشود.
- همانطور که از نام این روش پیداست، کلید تنها یک بار استفاده میشود و هیچگاه دوباره برای هیچ پیام دیگری به کار گرفته نخواهد شد.
به همین دلیل، پیام رمزگذاری شده برای تحلیلگر رمز در برابر حمله آسیبپذیر خواهد بود. کلیدی که برای رمز پد یک بار مصرف استفاده میشود را «پد» (صفحه | Pad) مینامیم چون روی صفحات یا پدهای کاغذی پرینت میشود.
چرا رمز یک بار مصرف غیر قابل شکستن است؟
بنابر وجود قابلیتهای زیر، کلید پد یک بار مصرف غیر قابل نفوذ و شکستن است.
- طول کلید به اندازه طول متن یا همان پیام مربوطه است.
- کلید واقعاً تصادفی است و خصوصاً کلید به صورت خودکار تولید میشود.
- هر کلید باید تنها یک بار مورد استفاده قرار بگیرد و هم لازم است به وسیله ارسال کننده و هم دریافت کننده تخریب شود.
- باید ۲ نسخه از یک کلید وجود داشته باشد، یکی به همراه ارسال کننده و دیگری هم به همراه دریافت کننده.
رمزگذاری در روش One Time Pad Cipher چگونه انجام میشود؟
برای رمزگذاری یا Encrypt کردن یک حرف، کاربر باید کلیدی را زیر متن اصلی بنویسد. حرف الفبای متن اصلی در بالا و حرف الفبای مربوط به کلید در سمت چپ قرار میگیرد. بُرش عرضی بدست آمده میان دو حرف، همان متن اصلی است. در تصویر زیر این روش رمزگذاری در قالب مثال بیشتر توصیف شده است.
رمزگشایی در روش One Time Pad Cipher چگونه انجام میشود؟
برای رمزگشایی یک حرف الفبا، کاربر حرف کلید در سمت چپ را بر میدارد و حرف الفبای متن رمزدار را در آن سطر پیدا میکند. حرف مربوط به متن اصلی در بالای ستون در جایی قرار داده شده است که کاربر میتواند متن رمزدار را پیدا کند.
پیادهسازی رمزنگاری پد یک بار مصرف در پایتون
پایتون دارای ماژول پیادهسازی بدریخت و بیظرافتی برای رمزنگاری پد یک بار مصرف است. این پکیج در پایتون «One-Time-Pad» نام دارد که شامل ابزار رمزگذاری خط فرمانی میشود که در آن از ساز و کار رمزگذاری مشابه با الگوریتم رمز پد یک بار مصرف استفاده شده است.
نصب پکیج رمزنگاری One-Time-Pad در پایتون
برای نصب ماژول One-Time-Pad در پایتون میتوان از دستور زیر در خط فرمان پایتون استفاده کرد.
pip install onetimepad
اگر بخواهیم از این ماژول در خط فرمان پایتون استفاده کنیم، میتوانیم دستور زیر را اجرا کنیم.
onetimepad
کدهای زیر نمونهای برای ایجاد و پیادهسازی رمز پد یک بار مصرف است.
1import onetimepad
2
3cipher = onetimepad.encrypt('One Time Cipher', 'random')
4print("Cipher text is ")
5print(cipher)
6print("Plain text is ")
7msg = onetimepad.decrypt(cipher, 'random')
8
9print(msg)
- نکته: اگر طول کلید کمتر از طول پیام اصلی باشد، شکستن پیام رمزگذاری شده بسیار آسان خواهد بود.
در همه موارد کلید لزوماً تصادفی نیست که این رمزنگاری پد یک بار مصرف را به ابزاری با ارزش تبدیل میکند.
رمزنگاری متقارن و نامتقارن در پایتون
در این بخش به رمزنگاری متقارن و نامتقارن در پایتون پرداخته شده است. ابتدا رمزنگاری متقارن در پایتون را شرح میدهیم.
رمزنگاری متقارن در پایتون
در «رمزنگاری متقارن» (Symmetric Cryptography)، فرایند رمزگذاری و رمزگشایی از کلیدی یکسان استفاده میکنند. این روش را «رمزنگاری کلید سری» (Secret Key Cryptography) هم مینامند. ویژگیهای اصلی رمزنگاری متقارن در ادامه آمده است.
- این روش سادهتر و سریعتر است.
- دو طرف ارتباط، کلید رمزنگاری را به شکلی ایمن تبادل میکنند.
نقطه ضعف رمزنگاری متقارن چیست ؟
نقطه ضعف اصلی روش رمزنگاری متقارن این است که اگر کلید لو رفته باشد و متجاوز به آن دسترسی پیدا کند، به راحتی میتواند پیام اصلی را تغییر دهد و این مسئله یک عامل خطرآفرین محسوب میشود.
استاندارد رمزنگاری داده یا DES چیست؟
محبوبترین و رایجترین الگوریتم کلید متقارن، «استاندارد رمزگذاری داده» (Data Encryption Standard) است که با مخفف آن یعنی «DES» هم خطاب میشود. پایتون دارای پکیجی به نام «pyDES» است که در آن منطق پُشت الگوریتم DES وجود دارد و با استفاده از آن میتوان این الگوریتم را در پایتون پیادهسازی کرد. نصب این پکیج به صورت زیر انجام میشود.
pip install pyDES
در ادامه برنامهای ساده برای پیادهسازی الگوریتم DES آمده است.
1import pyDes
2
3data = "DES Algorithm Implementation"
4k = pyDes.des("DESCRYPT", pyDes.CBC, "", pad=None, padmode=pyDes.PAD_PKCS5)
5d = k.encrypt(data)
6
7print "Encrypted: %r" % d
8print "Decrypted: %r" % k.decrypt(d)
9assert k.decrypt(d) == data
الگوریتم DES برای متغیرpadmode فراخوانی میشود که برای هر پیادهسازی الگوریتم DES تمام پکیجها را دریافت و رمزگذاری و رمزگشایی را به صورت تعیین شده دنبال میکند. نتیجه حاصل شده از کدهای بالا در تصویر زیر نشان داده شده است.
رمزنگاری نامتقارن در پایتون چگونه است؟
به «رمزنگاری نامتقارن» (Asymmetric Cryptography)، «رمزنگاری کلید عمومی» (Public Key Cryptography) هم گفته میشود. این روش برعکس رمزنگاری متقارن عمل میکند. این یعنی رمزنگاری نامتقارن به ۲ کلید نیاز دارد؛ یکی برای رمزگذاری و دیگری برای رمزگشایی استفاده میشود. کلید عمومی برای رمزگذاری و کلید خصوصی برای رمزگشایی به کار میرود.
نقطه ضعف رمزنگاری نامتقارن چیست ؟
دو نقطه ضعف کلیدی روش رمزنگاری کلید عمومی در ادامه آمده است.
- به دلیل طول این کلید، سرعت رمزگذاری در این روش کمتر است.
- مدیریت کلید در این روش بسیار حیاتی و مهم است.
کدهای برنامه زیر نحوه عملکرد رمزنگاری کلید نامتقارن را به زبان پایتون و با استفاده از الگوریتم RSA و پیادهسازی آن نشان میدهند. در بخش بعدی به شرح الگوریتم RSA پرداخته شده است.
1from Crypto import Random
2from Crypto.PublicKey import RSA
3import base64
4
5def generate_keys():
6 # key length must be a multiple of 256 and >= 1024
7 modulus_length = 256*4
8 privatekey = RSA.generate(modulus_length, Random.new().read)
9 publickey = privatekey.publickey()
10 return privatekey, publickey
11
12def encrypt_message(a_message , publickey):
13 encrypted_msg = publickey.encrypt(a_message, 32)[0]
14 encoded_encrypted_msg = base64.b64encode(encrypted_msg)
15 return encoded_encrypted_msg
16
17def decrypt_message(encoded_encrypted_msg, privatekey):
18 decoded_encrypted_msg = base64.b64decode(encoded_encrypted_msg)
19 decoded_decrypted_msg = privatekey.decrypt(decoded_encrypted_msg)
20 return decoded_decrypted_msg
21
22a_message = "This is the illustration of RSA algorithm of asymmetric cryptography"
23privatekey , publickey = generate_keys()
24encrypted_msg = encrypt_message(a_message , publickey)
25decrypted_msg = decrypt_message(encrypted_msg, privatekey)
26
27print "%s - (%d)" % (privatekey.exportKey() , len(privatekey.exportKey()))
28print "%s - (%d)" % (publickey.exportKey() , len(publickey.exportKey()))
29print " Original content: %s - (%d)" % (a_message, len(a_message))
30print "Encrypted message: %s - (%d)" % (encrypted_msg, len(encrypted_msg))
31print "Decrypted message: %s - (%d)" % (decrypted_msg, len(decrypted_msg))
با اجرای کدهای بالا، خروجی به صورت زیر خواهد بود.
الگوریتم RSA چیست ؟
الگوریتم RSA یک روش رمزگذاری کلید عمومی است و امنترین روش رمزگذاری به حساب میآید. این الگوریتم و نام آن یعنی RSA در سال ۱۹۷۸ (سال ۱۳۵۷ خورشیدی) توسط Shamir ،Rivest و Adleman اختراع شده است.
ویژگی های الگوریتم RSA
الگوریتم RSA دارای ویژگیها و خصوصیتهای زیر است.
- الگوریتم RSA تصاعدی محبوب در میدانی محدود روی اعداد صحیح از جمله اعداد اول به حساب میآید.
- اعداد صحیحی که به وسیله این روش مورد استفاده قرار میگیرند به میزان کافی بزرگ هستند تا حل آنها دشوار و سخت شود.
- دو مجموعه کلید در این الگوریتم وجود دارد؛ کلید خصوصی و کلید عمومی
برای کار با الگوریتم RSA باید گامهایی را دنبال کرد که هر کدام از آنها در ادامه آمده است.
گام اول: تولید ماژول های RSA
مراحل ابتدایی با انتخاب ۲ عدد اول p و q شروع میشود و سپس باید ضرب آنها را محاسبه کرد که در اینجا نتیجه در متغیر N ذخیره میشود.
1N=p*q
گام دوم: عدد مشتق شده e
عدد e را به عنوان عدد مشتق شده در نظر بگیرید که باید بزرگتر از یک و کوچکتر از و باشد. شرط اصلی این خواهد بود که نباید هیچ مقسوم علیه مشترکی به غیر از یک از و وجود داشته باشد.
گام سوم: کلید عمومی
جفت عدد مشخص شده n و e کلید عمومی RSA را تشکیل میدهند و این کلید، عمومی شده است.
گام چهارم: کلید خصوصی
در این گام کلید خصوصی d با استفاده از اعداد q ،p و e محاسبه میشود. رابطه ریاضی بین این اعداد در ادامه آمده است.
فرمول بالا رابطهای اساسی برای الگوریتم تعمیمیافته اقلیدس است که p و q را به عنوان پارامترهای ورودی دریافت میکند.
فرمول رمزگذاری RSA
فرستندهای را در نظر بگیرید که پیام حاوی متن اصلی و بدون رمز را به کلاینتی میفرستد که کلید عمومی آن (n,e) است. برای رمزگذاری پیام متن اصلی در این سناریو، از سینتکس زیر استفاده میشود.
1C = Pe mod n
فرمول رمزگشایی RSA
فرایند رمزگشایی بسیار سر راست و حاوی تجزیه و تحلیلهایی برای محاسبات با رویکردی متقارن است. به فرض دریافت کننده C کلید خصوصی d را دارد، نتیجه به صورت زیر محاسبه خواهد شد.
1Plaintext = Cd mod n
آموزش ایجاد کلیدهای RSA در پایتون
در این بخش بر پیادهسازی گام به گام الگوریتم RSA با پایتون تمرکز میکنیم.
تولید کلیدهای RSA
برای تولید کلیدهای RSA باید گامهای زیر را طی کنیم.
- ایجاد ۲ عدد اول بزرگ به نامهای p و q که ضرب آنها هم در n ذخیره خواهد شد، یعنی داریم: n=p*q
- تولید یک عدد تصادفی که نسبت به و اول باشد و این عدد را هم e مینامیم.
- محاسبه معکوس ماژولار e که معکوس محاسبه شده را d خواهیم نامید.
الگوریتم های مربوط به تولید کلیدهای RSA
برای تولید کلیدهای RSA با پایتون نیاز به پیادهسازی ۲ الگوریتم اساسی با ایجاد ماژولهای Cryptomath و Rabin Miller وجود دارد که در ادامه به آنها پرداخته شده است.
ماژول Cryptomath
کد منبع ماژول Cryptomath که تمام پیادهسازیهای اساسی الگوریتم RSA به دنبال آن انجام میشوند در ادامه آمده است.
1def gcd(a, b):
2 while a != 0:
3 a, b = b % a, a
4 return b
5
6def findModInverse(a, m):
7 if gcd(a, m) != 1:
8 return None
9 u1, u2, u3 = 1, 0, a
10 v1, v2, v3 = 0, 1, m
11
12 while v3 != 0:
13 q = u3 // v3
14 v1, v2, v3, u1, u2, u3 = (u1 - q * v1), (u2 - q * v2), (u3 - q * v3), v1, v2, v3
15 return u1 % m
ماژول Rabin Miller
کدهای منبع ماژول Rabin Miller که پیادهسازی اساسی الگوریتم RSA را دنبال میکند در ادامه آمده است.
1import random
2def rabinMiller(num):
3 s = num - 1
4 t = 0
5
6 while s % 2 == 0:
7 s = s // 2
8 t += 1
9 for trials in range(5):
10 a = random.randrange(2, num - 1)
11 v = pow(a, s, num)
12 if v != 1:
13 i = 0
14 while v != (num - 1):
15 if i == t - 1:
16 return False
17 else:
18 i = i + 1
19 v = (v ** 2) % num
20 return True
21def isPrime(num):
22 if (num 7< 2):
23 return False
24 lowPrimes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61,
25 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151,
26 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241,
27 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313,317, 331, 337, 347, 349,
28 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449,
29 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569,
30 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661,
31 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787,
32 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907,
33 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997]
34
35 if num in lowPrimes:
36 return True
37 for prime in lowPrimes:
38 if (num % prime == 0):
39 return False
40 return rabinMiller(num)
41def generateLargePrime(keysize = 1024):
42 while True:
43 num = random.randrange(2**(keysize-1), 2**(keysize))
44 if isPrime(num):
45 return num
تمام کدهای مربوط به تولید کلیدهای RSA در ادامه آمده است.
1import random, sys, os, rabinMiller, cryptomath
2
3def main():
4 makeKeyFiles('RSA_demo', 1024)
5
6def generateKey(keySize):
7 # Step 1: Create two prime numbers, p and q. Calculate n = p * q.
8 print('Generating p prime...')
9 p = rabinMiller.generateLargePrime(keySize)
10 print('Generating q prime...')
11 q = rabinMiller.generateLargePrime(keySize)
12 n = p * q
13
14 # Step 2: Create a number e that is relatively prime to (p-1)*(q-1).
15 print('Generating e that is relatively prime to (p-1)*(q-1)...')
16 while True:
17 e = random.randrange(2 ** (keySize - 1), 2 ** (keySize))
18 if cryptomath.gcd(e, (p - 1) * (q - 1)) == 1:
19 break
20
21 # Step 3: Calculate d, the mod inverse of e.
22 print('Calculating d that is mod inverse of e...')
23 d = cryptomath.findModInverse(e, (p - 1) * (q - 1))
24 publicKey = (n, e)
25 privateKey = (n, d)
26 print('Public key:', publicKey)
27 print('Private key:', privateKey)
28 return (publicKey, privateKey)
29
30def makeKeyFiles(name, keySize):
31 # Creates two files 'x_pubkey.txt' and 'x_privkey.txt'
32 (where x is the value in name) with the the n,e and d,e integers written in them,
33 # delimited by a comma.
34 if os.path.exists('%s_pubkey.txt' % (name)) or os.path.exists('%s_privkey.txt' % (name)):
35 sys.exit('WARNING: The file %s_pubkey.txt or %s_privkey.txt already exists! Use a different name or delete these files and re-run this program.' % (name, name))
36 publicKey, privateKey = generateKey(keySize)
37 print()
38 print('The public key is a %s and a %s digit number.' % (len(str(publicKey[0])), len(str(publicKey[1]))))
39 print('Writing public key to file %s_pubkey.txt...' % (name))
40
41 fo = open('%s_pubkey.txt' % (name), 'w')
42 fo.write('%s,%s,%s' % (keySize, publicKey[0], publicKey[1]))
43 fo.close()
44 print()
45 print('The private key is a %s and a %s digit number.' % (len(str(publicKey[0])), len(str(publicKey[1]))))
46 print('Writing private key to file %s_privkey.txt...' % (name))
47
48 fo = open('%s_privkey.txt' % (name), 'w')
49 fo.write('%s,%s,%s' % (keySize, privateKey[0], privateKey[1]))
50 fo.close()
51# If makeRsaKeys.py is run (instead of imported as a module) call
52# the main() function.
53if __name__ == '__main__':
54 main()
کلید عمومی و کلیدهای خصوصی تولید و در فایلهای مربوطهای که در خروجی زیر نشان داده شده ذخیره میشوند.
رمزگذاری با الگوریتم رمز RSA در پایتون
در این بخش روی پیادهسازی رمزگذاری RSA و توابع مربوط به آن تمرکز شده است.
ماژولهای استفاده شده برای الگوریتم رمزگذاری در ادامه آمده است.
1from Crypto.PublicKey import RSA
2from Crypto.Cipher import PKCS1_OAEP
3from Crypto.Signature import PKCS1_v1_5
4from Crypto.Hash import SHA512, SHA384, SHA256, SHA, MD5
5from Crypto import Random
6from base64 import b64encode, b64decode
7hash = "SHA-256"
در کدهای بالا، به منظور امنیت بالاتر مقدار «هش» (Hash | درهمسازی) با «SHA-256» مقداردهی شده است. برای تولید کلیدهای جدید یا همان جفت کلیدهای عمومی و خصوصی از تابعی استفاده شده است که کدهای آن در ادامه آمدهاند.
1def newkeys(keysize):
2 random_generator = Random.new().read
3 key = RSA.generate(keysize, random_generator)
4 private, public = key, key.publickey()
5 return public, private
6def importKey(externKey):
7 return RSA.importKey(externKey)
برای رمزگذاری از تابع زیر استفاده میشود که از الگوریتم RSA تبعیت میکند.
1def encrypt(message, pub_key):
2 cipher = PKCS1_OAEP.new(pub_key)
3 return cipher.encrypt(message)
دو پارامترmessage وpub_key اجباری هستند که به کلید عمومی مربوط میشوند. برای رمزگذاری از یک کلید عمومی استفاده میشود و برای رمزگشایی هم از کلید خصوصی استفاده شده است. در ادامه این بخش، برنامه کامل مربوط به عملیات رمزگذاری با RSA در پایتون آمده است.
1from Crypto.PublicKey import RSA
2from Crypto.Cipher import PKCS1_OAEP
3from Crypto.Signature import PKCS1_v1_5
4from Crypto.Hash import SHA512, SHA384, SHA256, SHA, MD5
5from Crypto import Random
6from base64 import b64encode, b64decode
7hash = "SHA-256"
8
9def newkeys(keysize):
10 random_generator = Random.new().read
11 key = RSA.generate(keysize, random_generator)
12 private, public = key, key.publickey()
13 return public, private
14
15def importKey(externKey):
16 return RSA.importKey(externKey)
17
18def getpublickey(priv_key):
19 return priv_key.publickey()
20
21def encrypt(message, pub_key):
22 cipher = PKCS1_OAEP.new(pub_key)
23 return cipher.encrypt(message)
رمزگشایی با الگوریتم رمز RSA در پایتون
این بخش ادامه بخش قبلی است که در آن پیادهسازی گام به گام رمزگذاری با استفاده از الگوریتم RSA دنبال شد و حالا در این بخش به نحوه پیادهسازی رمزگشایی پرداختهایم. تابعی که برای رمزگشایی متن رمزدار مورد استفاده قرار میگیرد در ادامه آمده است.
1def decrypt(ciphertext, priv_key):
2 cipher = PKCS1_OAEP.new(priv_key)
3 return cipher.decrypt(ciphertext)
برای رمزنگاری کلید عمومی یا همان رمزنگاری کلید نامتقارن، این مسئله بسیار اهمیت دارد که ۲ قابلیت مهم «احراز هویت» (Authentication) و «صدور مجور» (Authorization) را حفظ کنیم. برای این منظور در ادامه به هر یک از این دو عامل مهم پرداختهایم.
احراز هویت برای رمزگشایی با الگوریتم رمز RSA در پایتون
احراز هویت فرایندی است برای تایید اینکه ارسال کننده تنها فردی خواهد بود که پیام را انتقال میدهد. این قابلیت عملکردی در ادامه با پایتون پیادهسازی شده است.
1def sign(message, priv_key, hashAlg="SHA-256"):
2 global hash
3 hash = hashAlg
4 signer = PKCS1_v1_5.new(priv_key)
5
6 if (hash == "SHA-512"):
7 digest = SHA512.new()
8 elif (hash == "SHA-384"):
9 digest = SHA384.new()
10 elif (hash == "SHA-256"):
11 digest = SHA256.new()
12 elif (hash == "SHA-1"):
13 digest = SHA.new()
14 else:
15 digest = MD5.new()
16 digest.update(message)
17 return signer.sign(digest)
صدور مجوز برای رمزگشایی با الگوریتم رمز RSA در پایتون
صدور مجوز به وسیله متُد یا تابعverify امکانپذیر میشود که کدهای آن در در ادامه آمده است.
1def verify(message, signature, pub_key):
2 signer = PKCS1_v1_5.new(pub_key)
3 if (hash == "SHA-512"):
4 digest = SHA512.new()
5 elif (hash == "SHA-384"):
6 digest = SHA384.new()
7 elif (hash == "SHA-256"):
8 digest = SHA256.new()
9 elif (hash == "SHA-1"):
10 digest = SHA.new()
11 else:
12 digest = MD5.new()
13 digest.update(message)
14 return signer.verify(digest, signature)
امضای دیجیتال به همراه جزئیات ارسال کننده و دریافت کننده تایید میشود. این باعث خواهد شد وزن بیشتری به لحاظ امنیتی اعمال شود.
رمزگشایی رمز RSA در پایتون
با استفاده از کدهای زیر میتوان رمزگشایی رمز RSA را با پایتون پیادهسازی کرد.
1from Crypto.PublicKey import RSA
2from Crypto.Cipher import PKCS1_OAEP
3from Crypto.Signature import PKCS1_v1_5
4from Crypto.Hash import SHA512, SHA384, SHA256, SHA, MD5
5from Crypto import Random
6from base64 import b64encode, b64decode
7hash = "SHA-256"
8
9def newkeys(keysize):
10 random_generator = Random.new().read
11 key = RSA.generate(keysize, random_generator)
12 private, public = key, key.publickey()
13 return public, private
14
15def importKey(externKey):
16 return RSA.importKey(externKey)
17
18def getpublickey(priv_key):
19 return priv_key.publickey()
20
21def encrypt(message, pub_key):
22 cipher = PKCS1_OAEP.new(pub_key)
23 return cipher.encrypt(message)
24
25def decrypt(ciphertext, priv_key):
26 cipher = PKCS1_OAEP.new(priv_key)
27 return cipher.decrypt(ciphertext)
28
29def sign(message, priv_key, hashAlg = "SHA-256"):
30 global hash
31 hash = hashAlg
32 signer = PKCS1_v1_5.new(priv_key)
33
34 if (hash == "SHA-512"):
35 digest = SHA512.new()
36 elif (hash == "SHA-384"):
37 digest = SHA384.new()
38 elif (hash == "SHA-256"):
39 digest = SHA256.new()
40 elif (hash == "SHA-1"):
41 digest = SHA.new()
42 else:
43 digest = MD5.new()
44 digest.update(message)
45 return signer.sign(digest)
46
47def verify(message, signature, pub_key):
48 signer = PKCS1_v1_5.new(pub_key)
49 if (hash == "SHA-512"):
50 digest = SHA512.new()
51 elif (hash == "SHA-384"):
52 digest = SHA384.new()
53 elif (hash == "SHA-256"):
54 digest = SHA256.new()
55 elif (hash == "SHA-1"):
56 digest = SHA.new()
57 else:
58 digest = MD5.new()
59 digest.update(message)
60 return signer.verify(digest, signature)
هک کردن رمز RSA
هک کردن رمز RSA که در آن از اعداد اول کوچک استفاده شده، امکانپذیر است، اما اگر با اعداد بزرگ استفاده شود، غیرممکن خواهد بود.
در ادامه به شرح دلایلی پرداخته شده است که مشخص میکنند چرا هک کردن رمز RSA دشوار است.
- حمله Brute Force مثمر ثمر نخواهد بود، چرا که تعداد کلیدهایی که باید امتحان شوند بسیار زیاد هستند. همچنین این روش نیازمند زمان بسیار زیادی هم خواهد بود.
- روش حمله دیکشنری هم در الگوریتم RSA مثمر ثمر واقع نخواهد شد، چون کلیدها عددی هستند و هیچ کاراکتری در آنها وجود ندارد.
- دنبال کردن تجزیه و تحلیل فرکانسی کاراکترها نیز بسیار دشوار خواهد بود، زیرا یک بلوک واحد کاراکترهای متعددی را نمایندگی میکند.
- هیچ روش و ترفند ریاضی برای هک کردن رمز RSA وجود ندارد.
رابطه ریاضی رمزگشایی RSA به صورت زیر است.
به کمک اعداد فرد کوچک، میتوان درهمسازی یا همان هش کردن رمز RSA را امتحان کرد و کدهای ساده مربوط انجام این کار در ادامه آمده است.
1def p_and_q(n):
2 data = []
3 for i in range(2, n):
4 if n % i == 0:
5 data.append(i)
6 return tuple(data)
7
8def euler(p, q):
9 return (p - 1) * (q - 1)
10
11def private_index(e, euler_v):
12 for i in range(2, euler_v):
13 if i * e % euler_v == 1:
14 return i
15
16def decipher(d, n, c):
17 return c ** d % n
18 def main():
19 e = int(input("input e: "))
20 n = int(input("input n: "))
21 c = int(input("input c: "))
22
23 # t = 123
24 # private key = (103, 143)
25 p_and_q_v = p_and_q(n)
26 # print("[p_and_q]: ", p_and_q_v)
27 euler_v = euler(p_and_q_v[0], p_and_q_v[1])
28
29 # print("[euler]: ", euler_v)
30 d = private_index(e, euler_v)
31 plain = decipher(d, n, c)
32 print("plain: ", plain)
33if __name__ == "__main__":
34 main()
کدهای بالا خروجی زیر را تولید خواهند کرد.
جمعبندی
در این مطلب سعی شد تا حد امکان به طور جامع به تمام مباحث رمزنگاری در پایتون پرداخته شود. بسیاری از الگوریتمهای رمزنگاری در پایتون از جمله رمزنگاری سزار، رمزنگاری نامتقارن، DES ،RSA در پایتون و سایر موارد در این نوشته معرفی و مثالهایی عملی به همراه کدهای برنامه ارائه شدند. امید است این نوشتار مفید واقع شود.