ایجاد: ۱۵:۴۵ ۱۳۹۲/۸/۱۵
ویرایش: ۱۴:۱۲ ۱۳۹۲/۱۱/۹

آموزش‌ها »
رمزنگاری، هش، عملیات بیتی

تذکر: php, javascript دو زبانی هستند که عمده برنامه‌های تحت وب در سمت سرور و کلاینت توسط آنها کنترل می‌شود و به همین دلیل تمرکز ما در این مطلب، بر روی این دو زبان است. اما به دلیل کاربرد گسترده رمزنگاری، در سایر زبان‌ها (جاوا و سی و پایتون و ...) نیز کتابخانه‌ها و کلاس‌هایی برای این کار وجود دارد.

عملیات بیتی در زبان php و javascript

هر دو زبان php و javascript دارای عملگرهایی برای انجام عملیات بیتی هستند.
در سایت php.net می‌توانید راهنمای عملیات بیتی در php را ببینید و انواع اپراتورها را به همراه مثال مشاهده کنید.
در خصوص جاوا اسکریپت هم JavaScript: The less known parts / Bitwise Operators جزو مختصر و مفیدترین مطالبی است که در این زمینه دیده‌ام که توسط نویسنده کتاب JavaScript: The less known parts به صورت خلاصه بر روی وبلاگش قرار داده شده است.

رمزنگاری و انواع آن

به دلیل نیاز به پنهان کردن اطلاعات انتقالی (خصوصا در زمینه نظامی) دانشی به نام رمزنگاری شکل گرفت و با گسترش دانش ریاضی و کامپیوتر، به شدت تقویت شد.
رمزنگاری‌های اولیه، صرفا متکی به الگوریتم بود. مثلا یک الگوریتم ساده برای رمزکردن عدد می‌تواند «عدد ضرب در 2 به اضافه 5» باشد که برای باز کردن آن کافی است عکس آن الگوریتم «عدد منهای 5 تقسیم بر 2» استفاده شود. ضعف این کار این است که اگر الگوریتم لو برود، آن رمزنگاری فاقد ارزش می‌شود.

در اینگونه رمزنگاری‌ها که فقط وابسته به الگوریتم هستند، با دادن تعدادی ورودی و مشاهده خروجی، می‌توان الگوریتم استفاده شده را کشف کرد به همین دلیل امروزه رمزنگاری مبتنی بر پنهان نگاه داشتن الگوریتم، منسوخ شده‌است و در روش‌های جدید رمزنگاری، فرض بر این است که الگوریتم رمزنگاری معلوم است و آنچه پنهان است فقط «کلید» رمز است که چیزی شبیه پسورد است و به راحتی قابل تغییر.

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

مشکل رمزنگاری متقارن، انتقال کلید مشترک است. یعنی اگر کلید عوض شد، از چه کانالی مطمئنی باید به مقصد اطلاع داده شود که کلید عوض شده؟
رمزنگاری نامتقارن (که بر مبنای 2 کلید عمومی و خصوصی انجام می‌شود) در جهت حل این مشکل ایجاد شده است. از نظر سرعت، رمزگذاری متقارن (تک‌کلیدی) صدها برابر سریع‌تر است و به همین دلیل می‌توان از رمزنگاری نامتقارن برای رد و بدل یک کلید استفاده کرد و پس از معلوم شدن کلید نزد گیرنده و فرستنده، همان کلید برای تبادل داده با روش متقارن (که صدها برابر سریع‌تر است) استفاده شود.
در سیستم‌های رمزنگاری نامتقارن، گاهی از کلید عمومی برای رمزگذاری و از کلید خصوصی برای رمزگشایی استفاده می‌شود و گاهی نیز، بر عکس؛ کلید خصوصی برای رمزگذاری و کلید عمومی برای رمزگشایی به کار می‌رود (امضای دیجیتال).
دو کلید عمومی و خصوصی با یکدیگر متفاوت اما دارای یک رابطه خاص ریاضی با هم هستند. رابطه ریاضی بین این دو کلید نیز به صورتی است که کشف کلید خصوصی با در اختیار داشتن کلید عمومی در عمل ممکن نیست.

اصل «تازگی پیام‌ها»: یکی دیگر از اصول رمزنگاری آن است که باید مطمئن شویم هرپیام دریافتی، تازه و جدید است یا به عبارتی اخیرا فرستاده شده‌است. این بررسی برای جلوگیری از ارسال مجدد پیام‌های قدیمی توسط یک اخلالگر است که بدون اینکه بداند محتوای پیام‌های شنود شده قدیمی چیست، آن را ارسال کرده است. یکی از ساده‌ترین روش‌های پیاده‌سازی این نیاز این است که پیام رمز شده دارای یک مهر زمانی باشد که تا زمان معینی (مثلا 30 ثانیه) معتبر باشد و پیامی که مهر زمانی آن قدیمی بود، حذف شود.
این مطلب هنوز تکمیل نشده است............

هَش یعنی چه و تفاوت آن با رمزنگاری چیست؟

به روش (الگوریتم) ی که حجم دلخواهی از داده را به به یک عدد طبیعی تبدیل کند، hash یا «در هم سازی» گفته می‌شود. این عدد می‌تواند بعدا به کد hex و ... تبدیل شود.
به عنوان یک مثال ساده، یک الگوریتم هش می‌تواند به این صورت باشد که مجموع بیت‌های هر بایت داده را با هم جمع کرده و سپس بر تعداد بایت‌ها تقسیم کند.
در واقع هش، مانند یک امضاء برای یک رشته است که اگر رشته عوض شود، امضاء هم عوض می‌شود اما ممکن است چند رشته مختلف، یک امضای مشترک داشته باشند. پس هش، روشی برای رمزنگاری نیست چون از روی یک هش معین، نمی‌توان گفت که داده اولیه چه چیزی بوده است (هرچند داده‌ای وجود دارد که هش آن برابر همان هش معین است اما یافتن آن با تست رشته‌های مختلف، با توجه به سخت‌افزارهای فعلی، لزوما ممکن نیست)
برای هش کردن توابع زیادی توسط اساتید ریاضی و کامپیوتر پیشنهاد شده است که در سال‌های پیشین md5 یکی از پرکاربردترین آنها بود اما اخیرا sha بدلیل ایمنی بالاتر، بیشتر مورد استفاده قرار می‌گیرد.
یکی از کاربردهای هش، ذخیره پسورد است (در دیتابیس، سیستم‌عامل و ...). یعنی پسورد کاربر به صورت هش شده ذخیره می‌شود و زمانی که یک کاربر قصد Login داشت، پسوردی که وارد می‌کند را هش می‌کنند و با پسورد هش شده صحیح (که از قبل ذخیره شده) مقایسه می‌کنند. اگر مثل هم بود، هویت کاربر احراز می‌شود.

حمله به هش: پسوردهایی که به صورت هش شده در دیتابیس یا سیستم‌عامل ذخیره می‌شوند، گاهی ممکن است به دست یک نفوذگر بیفتد. در اینجا کشف پسورد اصلی (که اکنون هش شده آن را داریم) امری مطلوب است چون:

  • نفوذگر بجای سر و کله زدن با جداول وابست دیتابیس، به سادگی می‌تواند با آن پسورد به سیستم Login کنید و اطلاعات لازم را ببیند یا ویرایش کند
  • در برخی حملات (مثل SQL Injection) کاربر فقط می‌تواند اطلاعات را ببیند و نمی‌تواند آن را ویرایش کند (یا حداقل به راحتی نمی‌تواند ویرایش‌های دلخواه را در آن انجام دهد) اما اگر بتواند پسورد را با توجه به هش آن، به دست بیاورد، می‌تواند به راحتی به سیستم وارد شود.
  • در برخی سیستم‌ها که امنیت دارای اهمیت بسیار بالا و حساسی است، برخی اطلاعات (فایل/دیتابیس) با همان پسورد کاربرد رمزگذاری می‌شود. لذا بدون دانستن آن پسورد، دسترسی به فایل یا دیتابیس لزوما مفید نخواهد بود.
  • در برخی سیستم‌ها چند ادمین وجود دارد. اگر هر یک از آنها بتواند پسورد دیگری را (از روی هش آن که در دسترس وی می‌باشد) کشف کند، می‌تواند به عنوان دیگری Login کند و خرابکاری دلخواه خود را انجام دهد و آن را به نام دوستش ثبت کند!
  • اغلب افراد از یک پسورد مشخص، در چندجا استفاده می‌کنند مثلا پسورد بانکشان با پسورد ایمیلشان با پسورد دانشجویی آنها در سایت دانشگاه یکسان است! در اینصورت اگر نفوذگری که مثلا به سایت ضعیف دانشگاه نفوذ کرده، پسورد آن فرد را کشف کند، احتمالا می‌تواند با همان پسورد به سایر حساب‌های کاربری آن فرد در سایت‌های دیگر هم دست یابد.

روش‌هایی برای حمله به هش وجود دارد که به کمک آنها می‌توان با کمک سخت افزار خوب (مثل سوپرکامپیوترهای قابل اجاره که چندصدمیلیون محاسبه پیچیده در هر ثانیه انجام می‌دهند) در مدت زمانی معقول (کمتر از یک هفته) به هش‌های ضعیف‌تر (همچون MD5) نفوذ کرد به همین دلیل امروزه از هش‌های قوی‌تر مثل SHA-512 استفاده می‌شود.

رمزنگاری و هش در JAVASCRIPT

زبان PHP زبانی بزرگ و با توابع فراوان است که توابع رمزنگاری و هش بسیاری را داراست. اما زبان جاوا اسکریپت اینگونه نیست. حال راه حل چیست؟ آیا می‌توان در سمت کلاینت از توابع هش و رمزنگاری استفاده کرد؟ پاسخ مثبت است! هش و رمزنگاری، یک الگوریتم مشخص دارد که توسط هر زبانی قابل پیاده سازی است. در برخی زبان‌ها مثل php به صورت built-in است و در برخی زبان‌ها به صورت جدا لازم است آن الگوریتم پیاده سازی و مورد استفاده قرار گیرد که در مورد جاوا اسکریپت، موارد زیر تنها نمونه کوچکی از کدهای موجود است:
  • PHP JS
    این پروژه زیبا، توابعی php را که در js قابل پیاده‌سازی بوده، پیاده کرده است. از جمله این توابع، توابع هش (مانند md5) است.
  • CryptoJS
    یک کتابخانه کامل جاوا اسکریپتی برای رمز کردن و رمزگشایی از داده‌ها
    MD5, SHA-1, SHA-2, SHA-3, RIPEMD-160, AES, DES, Triple DES, Rabbit, RC4, RC4Drop و ... همگی در این کد js فراهم آمده است.
  • jsEncrypt
    یک کتابخانه جاوا اسکریپتی برای کار با کلید عمومی و خصوصی که با OpenSSL هماهنگ است.
  • jCryption
    جی‌کریپشن، یک پلاگین جی‌کوئری است که از دو کتابخانه فوق (CryptoJS+jsEncrypt) در سمت کلاینت و open ssl در برنامه php سمت سرور استفاده کرده تا شما به راحتی بتوانید بدون استفاده از SSL ارتباطی ایمن بین سرور و کلاینت داشته باشید که قابل شنود نیست.
    روش کار آن نیز بسیار ساده و جالب است. ابتدا سرور کلید عمومی خود را به کلاینت می‌فرستد. در سمت کلاینت، js یک کلید رندوم مثل 8xwFJubSzwajJE3dbSku3QvXk3 تولید می‌کند و آن را با کلید عمومی سرور رمز کرده و به سرور می‌فرستد. سرور آن را با کلیک خصوصی باز کرده و متوجه کلید رندوم ایجاد شده در کلاینت می‌شود و آن را با مجددا با همان کلید به روش AES رمزگذاری کرده و به کلاینت می‌فرستد. کلاینت آن را با کلیدش باز می‌کند و اگر درست بود، متوجه می‌شود که سرور کلید را به درستی متوجه شده است. حال از این لحظه به بعد، تمام ارتباطات بین سرور و کلاینت با همین کلید (8xwFJubSzwajJE3dbSku3QvXk3) و به روش AES رد و بدل خواهد شد.

یادداشت‌های مرتبط
  1. موثرترین روش برنامه‌نویسان برای مقابله با کی‌لاگر ها
  2. نکاتی در مورد نسخه جدید PHP 5.5

... لیست تمام آموزش‌ها