Designer & Developer
رمزگذاری داده ها با استفاده از الگوریتم های نامتقارن و کتابخانه phpseclib
این روز ها کم تر کسی پیدا می شود که به اهمیت ارسال داده ها به صورت امن پی نبرده و خواستار امنیت بیشتر در فضای مجازی و تبادلات روزانه اش نباشد . اگر شما هم برنامه نویس هستید قطعا برایتان جذاب خواهد بود که بدانید چگونه می توانید با استفاده صحیح از رمزنگاری های متقارن و نامتقارن امنیت کاربران خود را بالا ببرید و حتی در صورت هک شدن سرور به هکر ها اجازه دسترسی به اطلاعات کاربرانتان را ندهید.
اما رمزنگاری چیست ؟ رمزنگاری به صورت خلاصه ترجمه داده های ارسالی با استفاده از یک کلید و الگوریتم رمزنگاری به متن رمز (ciphertext) می باشد. اطلاعات بیشتر در ویکی پدیا
انواع الگوریتم های رمزنگاری
- الگوریتم های رمزنگاری متقارن ( Symmetric ) : در این نوع از الگوریتم ها از یک کلید برای رمزگذاری ( encryption ) و رمزگشایی ( decryption ) داده های استفاده می شود . مثل : Triple DES , Blowfish, Twofish و AES
- الگوریتم های رمزنگاری نامتقارن ( Asymmetric ) : در این نوع رمزنگاری از دوکلید برای رمزگذاری و رمزگشایی استفاده می شود از این دسته هم میتوان به رمزنگاری های :Diffie-Hellman, RSA, ECC, ElGamal, DSA اشاره کرد.
در الگوریتم های متقارن ( Symmetric ) تنها یک کلید برای رمزگذاری و رمزگشایی وجود دارد . هم فرستنده و هم دریافت کننده پیام باید یک کلید رمزنگاری داشته باشند که از این کلید هم برای رمزگذاری و هم برای رمزگشایی پیام استفاده می شود مشخص است که استفاده از این نوع الگوریتم های رمزنگاری به تنهایی برای تبادل اطلاعات بین فرستنده و دریافت کننده باعث ایجاد یک ارتباط آسیب پذیر می شود. این نوع رمزنگاری برای رمزنگاری فایل ها و داده های شخصی مناسب است.
در الگوریتم های نامتقارن ( Asymmetric ) دو کلید رمزنگاری وجود دارد : الف) کلید عمومی ( public key ) ب) کلید خصوصی ( private key ) . در این نوع الگوریتم داده هایی که با استفاده از کلید عمومی رمزگذاری میشوند تنها با استفاده کلید خصوصی قابل رمزگشایی هستند.
در واقع دریافت کننده کلید عمومی خود را در اختیار فرستنده می گذارد و فرستنده پیام خود را با آن رمزگذاری و ارسال می کند و تنها درصورتی که دریافت کننده کلید خصوصیی مطابق با آن کلید عمومی داشته باشد می تواند پیام را بخواند .
انتخاب الگوریتم رمزنگاری مناسب
الگوریتم های رمزنگاری قدرتمند بر اساس معادلات پیشرفته ریاضی طراحی شده اند و طراحی یک رمزنگاری اختصاصی کاری بسیار دشوار و پیچیده است برای همین بیشتر شرکت ها و کاربران از استاندارد های ارائه شده توسط موسسه ملی و فناوری استاندارد های آمریکا (NIST) استفاده می کنند .
این موسسه سه الگوریتم نامتقارن RSA , DSA و ECDSA را به عنوان الگوریتم های نامتقارن استاندارد ارائه کرده است که از بین این سه الگوریتم الگوریتم ECDSA یک الگوریتم نسباتا جدید است به همین دلیل استفاده از آن متداول نیست و بیشتر از دو الگوریتم رمزنگاری RSA و DSA استفاده می شوده که از بین دو الگوریتم رمزنگاری ذکر شده هم الگوریتم RSA به این دلیل که می تواند کلید های بزرگ تر و طولانی تری را ارائه دهد انتخاب می شود (اطلاعات بیشتر).
مشکل الگوریتم RSA
تا به اینجای کار مشاهده کردیم که الگوریتم های رمزنگاری نامتقارن مانند RSA انتخاب بهتری برای تبادل اطلاعات بین فرستنده و دریافت کننده پیام می باشد و از بین آن ها هم الگوریتم RSA بهتر است اما این الگوریتم یک مشکل بسیار بزرگ دارد و آن این است که با استفاده از این الگوریتم تنها می توانیم اطلاعاتی با سایز بسیار کم را رمزگذاری کنیم مثلا اگر شما از یک کلید 2048 بایتی استفاده کنید تنها می توانید 256 بایت متن رمزگذاری کنید .
راه حل
راه حل این مشکل این است که پیام ارسالی را با استفاده از یک الگوریتم متقارن رمزگذاری کنیم و بعد کلید رمزنگاری را با استفاده از الگوریتم نامتقارن رمزگذاری کنیم و به همراه پیام ارسال کنیم .
وقتی که پیام به کاربر نهایی رسید او هم کلید رمزنگاری متقارن را دارد و هم پیام را ، پس اول کلید را با استفاده از رمزنگاری نامتقارن رمزگشایی می کند و سپس از آن برای رمزگشایی پیام استفاده می کند.
مراحل کار به صورت کامل
الف ) رمزگذاری پیام :
- دریافت کننده پیام یک کلید رمزنگاری با استفاده از الگوریتم نامتقارن می سازد و کلید عمومی را برای فرستنده می فرستد.
- فرستنده هم به صورت تصادفی یک کلید رمزنگاری متقارن می سازد و از آن برای رمزگذاری پیام استفاده می کند.
- فرستنده پیام را با استفاده از کلید الگوریتم رمزنگاری متقارن رمزگذاری می کند
- فرستنده کلید خصوصی الگوریتم متقارن را با استفاده از کلید عمومی ارسال شده توسط دریافت کننده رمزگذاری می کند
- فرستنده پیام رمزگذاری شده را با کلید رمزنگاری شده به هم متصل می کند .
- فرستنده پیام را ارسال می کند.
ب ) رمزگشایی پیام :
حالا کافیست دریافت کننده دقیقا عکس عمل بالا را انجام دهد یعنی :
- دریافت کننده کلید الگوریتم متقارن را از پیام استخراج می کند .
- آن را با استفاده از کلید خصوصی الگوریتم نامتقارن رمزگشایی می کند .
در مرحله آخر هم پیام را استفاده از کلید رمزگشایی شده رمزگشایی می کند .
پیاده سازی راه حل با استفاده از کتابخانه phpseclib
برای این کار ما از کتابخانه PHP Secure Communications Library استفاده می کنیم . این کتابخانه با استفاده از پلاگین های open_ssl و mcrypt رمزنگاری های RSA, DES, 3DES, RC4, Rijndael, AES, Blowfish, Twofish, SSH-1, SSH-2, SFTP, and X.509 را پیاده سازی کرده است که می توانید آن را با استفاده از composer بر روی پروژه خود نصب کنید .
خیلی خب حالا باید به پیاده سازی راه حل گفته شده بپردازیم :
ما با استفاده از کلاس RSA کلید عمومی و خصوصی خود را می سازیم و باید دقت کنید که کلید خصوصی باید تا وقتی که برای رمزگشایی از آن استفاده نشده است در محل امنی نگه داری شود و کلید عمومی هم که برای فرستنده ارسال می شود .
$rsa = new Crypt_RSA();
$keys = $rsa->createKey(2048);
file_put_contents('key.pri',$keys['privatekey']);
file_put_contents('key.pub',$keys['publickey']);
تابع رمرگذاری
این تابع سه پارامتر ورودی دریافت می کند :
- $plaintext : متنی است که برای رمزگذاری ارائه می شود
- $asym_key : کلید عمومی که به فرستنده ارائه می شود
- $key_length : یک پارامتر اختیاری که نباید کمتر از 240 باشد و هرچه بیشتر باشد بهتر داده های ارسالی را از حملات بروت فروس در امان نگه می دارد .
function encrypt_message($plaintext,$asym_key,$key_length=150){
$rsa = new Crypt_RSA();
$rij = new Crypt_Rijndael();
// ساخت کلید رمزنگاری متقارن که در این مثال از الگوریتم
//Rijndael
//استفاده شده است
$sym_key = crypt_random_string($key_length);
// رمزگذاری پیام با کلید بالا
$rij->setKey($sym_key);
$ciphertext = $rij->encrypt($plaintext);
$ciphertext = base64_encode($ciphertext);
// رمزگذاری کلید رمزنگاری متقارن با کلید عمومی دریافت شده
$rsa->loadKey($asym_key);
$sym_key = $rsa->encrypt($sym_key);
// اینکود کردن کلید رمزنگاری متقارن با استفاده Base64
$sym_key = base64_encode($sym_key);
$len = strlen($sym_key); // دریافت طول کلید
$len = dechex($len); // 3 بایت اول پیام طول کلید می باشد
$len = str_pad($len,3,'0',STR_PAD_LEFT); // استفاده از تابع str_pad برای اینکه مطمئن شویم اندازه $len درست است
// اتصال سه متغییر $len,$sym_key و $ciphertext
$message = $len.$sym_key.$ciphertext;
return $message;
}
تابع رمزگشایی
این تابع هم دو ورودی دریافت می کند
- $message : پیامی که باید رمزگشایی شود
- $asym_key : کلید خصوصی دریافت کننده .
function decrypt_message($message,$asym_key){
$rsa = new Crypt_RSA();
$rij = new Crypt_Rijndael();
// استخراج کلید رمزنگاری متقارن
$len = substr($message,0,3);
$len = hexdec($len);
$sym_key = substr($message,0,$len);
//استخراج پیام
$message = substr($message,3);
$ciphertext = substr($message,$len);
$ciphertext = base64_decode($ciphertext);
// رمزگشایی کلید رمزنگاری Rijndael
$rsa->loadKey($asym_key);
$sym_key = base64_decode($sym_key);
$sym_key = $rsa->decrypt($sym_key);
// رمزگشایی پیام
$rij->setKey($sym_key);
$plaintext = $rij->decrypt($ciphertext);
return $plaintext;
}
سخن آخر
در این پست شما را انواع رمزنگاری ها و ترکیب آن ها با هم آشنا کردیم . مزیت ها و معایب الگوریتم های متقارن و نامتقارن را بررسی کردیم و امیدواریم حالا دید بهتری نسبت به الگوریتم های رمزنگاری و روش های آن ها داشته باشید .
می توانید سورس این پست را در گیت هاب هم مشاهده کنید .
مطلبی دیگر از این انتشارات
۲۴ تله ی رایج در اسکرام (بخش اول)
مطلبی دیگر از این انتشارات
دقیقا چه کارهایی میشه با Python انجام داد؟ 3 کاربرد اصلی پایتون
مطلبی دیگر از این انتشارات
آموزش زبان برنامهنویسی Rust - قسمت۷: مالکیت