50درصد تخفیف سورس فروشگاهی دیجی کالا + اپلیکیشن اندروید تا پایان این هفته - کد تخفیف : off50
با تخفیف میخرم

آموزش الگوریتم های رمزنگاری در php

  • آپدیت شده در تاریخ

آموزش الگوریتم های رمزنگاری در php

بروزرسانی در تاریخ ۵ آذر ۱۳۹۷

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

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

هش و رمزنگاری اطلاعات

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

تابع های معروف هش

تابع md5

 ابتدایی ترین تابع هش میباشد. این تابع به تنهایی امن نمیباشد زیرا در این زمان بسیاری از دیتابیس های بزرگی از این هش تو اینترنت وجود دارد و بادادن هش راحت عبارت اصلی پیدا میشود. به مثال زیر توجه کنید:

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

توجه کنید که که متغیر ها هرچیزی میتوانند باشند هش فقط نام روش است.

با اینکه به این نتیجه رسیدیم که تابع md۵ از امنیت بالایی برخوردار نمیباشد اما نگران نباشید چون php  در نسخه ی ۵ به بالا از تابع های crypt و password_hash  پشتیبانی میکند که مراتب از تابع md۵ از امنیت بیشتری برخوردارند.

تابع crypt

این تابع از تابع md۵ از امنیت بالاتری برخوردار است و خود تابع کلمه ی اضافی (salt) رندوم را اضافه میکند.توجه کنید که این تابع در نسخه های ۵ به بعد php  میتوان به صورت ۲ پارامتری نوشت و salt  به عنوان پارامتر دوم قرار گیرد.

ویا به صورت زیر که از شرط if نیز استفاده شده است.

دقت کنید فقط دز نسخه های php ۵ به بالا تابع crypt میتواند دو متغیر را بپذیرد و در نسخه های پایین تر salt  را نمیتوانیم به عنوان متغیر دوم تابع در نظر بگیریم.

تابع password_hash

کد بالا به این صورت است که ابتدا مقدار داده شده توسط تابع password_hash هش میشود و توسط دستور شرطی if  درستی کمه ی عبور وارد شده بررسی میشود.

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

هش قابل بازگشت نیست یعنی اگر اطلاعات و داده های شما نیاز به بازیابی ندارند میتوانید برای افزایش امنیت اطلاعات از هش و قواعد رمزنگاری در چهارچوب هش استفاده نمایید.

برای استفاده از الگوریتم های رمزنگاری در php میتوانید از تابع هایی ابتدایی مانند base۶۴_encode و نیز در سطح بالاتر از تابع mcrypt_decrypt استفاده نمایید که در ادامه توضیح خواهیم داد.

تابع base۶۴_decode 

یکی از ساده ترین تابع هایی است که برای رمز نگاری استفاده میشود که با تابع base۶۴_encode قابل بازگشت است.

و مقدار بازگشتی آن به صورت زیر است:

توجه کنید که رای کدگشایی اطلاعات(اطلاعاتی که قبلا کدگذاری شده‌اند) از تابع base۶۴_decode استفاده می‌کنیم.در واقع تابع بالا مقدار بازگشتی تابع base۶۴_decode  می باشد.در مقاله آموزشی الگوریتم های رمزنگاری در php ، به هیچ وجه توصیه نمی شود که از این تابع برای رمزنگاری پسوردها استفاده کنید و این قسمت طرفا یک نوع معرفی است.

تابع mcrypt_encrypt

 یکی از بهترین توابع الگوریتم های رمزنگاری در php است که از الگوریتم MCRYPT_BLOWFISH بهرو می برد که یکی از بهترین الگوریتم های رمزنگاری محسوب می شود ، به این صورت که یک رشته را بر اساس کلیدی که برای آن تعریف میکنیم ، رمز و سپس توس تابع بازگشت آن یعنی mcrypt_decrypt بازگشایی میکند.

بروزرسانی :

توابع زیرمجموعه mcrypt_ در نسخه php 7.1 منسوخ اعلام شده و  شما با خطای Deprecated مواجه می شوید و در نسخه های ۷٫۱ به بعد هم این تابع کاملا حذف شده و خطای Undefined Function نمایش داده می شود.

بنابراین توصیه می شود از این به بعد از تابع openssl_encrypt استفاده کنید.

مثال زیر نحوه استفاده از این تابع برای اینکریپت و دی-کریپت را نشان می دهد :

نحوه استفاده از تابع :

 

توصیه ما این است که برای رمزنگاری در php از توایع غیرقابل برگشت مثل hash , md5 و الگوریتم های sha1 استفاده کنید تا امنیت رمزهای عبور شما حتی با لو رفتن دیتابیس به هر روشی مثل sql injection افشا و اطلاعات اکانت کاربران در اختیار افراد قرار نگیرد.

موفق و پیروز باشید.

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

آموزش های رایگان بیشتر در اینستاگرام ما ...

NETPARADIS /
مطالب زیر را حتما بخوانید
دیدگاه کاربران (۲۴)

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

  1. فرزاد ۱۰ فروردین ۱۳۹۹

    سلام و تشکر از آموزش های عالی تون
    یه سوال ازاین میشه بجای JWT استفاده کرد برای امنیت لاگین و چک کردن؟
    چون JWT رو هر چی مطلاعه کردم نتونستم سر در بیارم واقعیت آموزش ۰ تا ۱۰۰ هم چیزی پیدا نکردم

    پاسخ
    1. حسن شفیعی ۱۰ فروردین ۱۳۹۹

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

      پاسخ
  2. امین ۳ آذر ۱۳۹۸

    سلام آقای شفیعی خسته نباشید
    اگه بخوایم اطلاعات کاربرا به طور مثال رمز عبورشون رو هش کنم و بخوام موقع خوندن از بانک از هش دربیاد به چه شکل هست ؟؟؟
    مرسی از مطالب خوبتون

    پاسخ
    1. حسن شفیعی ۶ آذر ۱۳۹۸

      سلام. ممنون خوشحالیم که مفید واقع شده.
      باید از رمزنگاری های دو طرفه مثل openssl استفاده کنید تا بتونید این کار رو انجام بدید که در آخر همین پست به جای mcrypt در ورژن جدید php معرفی شده
      موفق باشید.

      پاسخ
  3. امیر ۳ مرداد ۱۳۹۸

    سلام
    بین اینا کدوم بهتر است:
    md5
    sha1
    sha256
    sha384
    sha512
    و اینکه با هم استفاده کنیم خوبه؟
    مثل کد زیر:
    function HashPassword( $pw ) {
    for($i = 0; $i < 40000; $i++) {
    $pw = md5(md5(md5(base64_encode($pw . $pw . 'veteran' . $i) . $pw . $i * 5000 . md5($i))));
    }
    return $pw;
    }

    پاسخ
    1. حسن شفیعی ۳ مرداد ۱۳۹۸

      سلام. سری sha بهتر هست و ترکیبی هم اوکی هست و مشکلی نیست میتونید استفاده کنید.
      موفق باشید.

      پاسخ
  4. محمد جواد ۱۰ اردیبهشت ۱۳۹۸

    سلام . قسمتی که کد مربوط به openssl_encrypt رو به عنوان نمونه قرار دادین salt رو باید کجای کد اضافه کرد ؟

    پاسخ
    1. محمد جواد ۱۰ اردیبهشت ۱۳۹۸

      ممنون میشم یه نگاه هم به این نمونه کدی که لینکشو میزارم بکنید و بررسیش کنید
      https://stackoverflow.com/a/46872528/388994

      پاسخ
      1. حسن شفیعی ۱۱ اردیبهشت ۱۳۹۸

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

        پاسخ
    2. حسن شفیعی ۱۱ اردیبهشت ۱۳۹۸

      سلام. مقدار متغییرهای $secret_key و $secret_iv را میتونید تغییر بدید.
      و بعد کافیه که به تابع نوع عملیات و رشته را پاس بدید تا نتیجه برای شما برگشت داده بشه.
      موفق باشید.

      پاسخ
      1. محمد جواد ۱۳ اردیبهشت ۱۳۹۸

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

        پاسخ
      2. حسن شفیعی ۱۴ اردیبهشت ۱۳۹۸

        خیلی خوشحالیم که مطالب منتشر شده مفید واقع شده.
        چون از الگوریتم aes استفاده میشه می توان گفت که اندازه بلاک ۱۲۸بیت و کلید هم ۱۲۸،۱۹۲،۲۵۶ میتونه باشه.
        به هر حال مهم طول کاراکتر خروجی نیست و بدلیل داتشن کلید یا همان سالت به حدی امن است که به سادگی قابل کرک نیست. و بهتره برای ذخیره یا ارسال ان یکبار هم در آخر از base64 برای اینکد استفاده کنید تا کاراکترها به درستی منتقل ک خوانده بشوند.
        موفق باشید.

        پاسخ
  5. ایمان ۵ دی ۱۳۹۷

    بابت پاسخ گویی سریع سپاسگذارم 🙂
    یک سوال ، بعضی جاها دیدم که میگن نیاز به $iv نیست ، و بعضی از برنامه نویس ها اون رو خالی گذاشتن ، ایا خالی گذاشتن این مورد مشکلی به وجود خواهد آورد؟
    پیشاپیش بابت پاسخ تون سپاسگذارم.

    پاسخ
    1. حسن شفیعی ۵ دی ۱۳۹۷

      الگوریتم AES نیاز به ۱۶بایت برای پر کردن بلاک ها نیاز داره برای همین از تابع فوق برای محاسبه و ساختن یک رشته رندوم ۱۶ کاراکتری برای این رمزنگاری استفاده کردیم.
      لطفا داکیومنت خود php رو هم مطالعه و همچنین نتایج رو تست کنید. از iv برای دیکریپت کردن رمز استفاده کردیم و بله میتونید خالی بزارید
      http://www.php.net/manual/en/function.openssl-encrypt.php
      موفق باشید.

      پاسخ
  6. ایمان ۵ دی ۱۳۹۷

    سلام آقای شفیعی
    بابت زحمات ای که میکشید سپاسگذاریم.
    یک سوال داشتم ، من برنامه ام از رمزنگاری aes 256 cbc برای رمزنگاری استفاده کردم (بین کلاینت و سرور) و حالا نمیدونم چطور از این روش در php استفاده کنم ، ممنون میشم پاسخ بدید.
    من از ابزار : https://www.devglan.com/online-tools/aes-encryption-decryption
    برای تست استفاده میکنم ، لطفا یک مثال از روش رمزنگاری AES 256 CBC ذکر کنید ، با تشکر.

    پاسخ
    1. حسن شفیعی ۵ دی ۱۳۹۷

      سلام. خوشحالم که مطالب ارایه شده مفید واقع میشه.

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

      در ابتدا الگوریتم رمزنگاری خود رو بصورت یک ثابت در نظر گرفتیم که در مراحل بعدی بدون qoute کردن رشته از اون استفاده کنید.
      مرحله بعدی از openssl_random_pseudo_bytes برای ساخت یک کلید رمزنگاری ۲۵۶ بیت استفاده کردیم (در یک متغییر برای استفاده بعدی بصورت موقت ذخیره می کنیم.)

      بعد یک بردار اولیه برای رشته ایجاد می کنیم که آن هم برای شکستن رمز(decrypt) در آینده نیاز پیاده خواهیم کرد

      بعد با تابع openssl_encrypt() رشته مورد نظر را با الگوریتم aes 256 cbc کد می کنیم.

      توجه کنید چهار مقداری که دادیم عبارتند از $data : متغییر حاوی رشته ای که قصد کد کردن آن را داریم , الگوریتم رمزنگاری , کلید رمز , ۰ هم که به معنی آپشن های پیشفرض است که می توانید OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING هم قرار بدید و در نهایت کلید شکستن رمز.

      و به اینصورت خروجی ما بصورت کد شده با الگوریتم aes 256 cbc چاپ میشه که البته ما به جای ذخیره سازی کلید بازگردانی آن را با : به این رشته متصل کردیم (برای موارد حساس این مورد توصیه نمیشه و فقط جهت نمونه تست بود وگرنه شما باید این کلید رو جایی ذخیره کنید اگر قصد بازگردانه رشته اصلی را دارید)

      اگر احیانا کدهای شما اجرا نشد و با خطای call undefined function .. مواجه شدید توجه کنید که باید اکستنشن موردنظر روی سرور فعال باشه (بررسی از طریق تابع phpinfo() و فعال سازی از فایل php.ini )
      ;extension=php_openssl.dll
      همچنین ورژن php باید بالا باشه.

      موفق باشید.

      پاسخ
  7. محمد جواد ۵ آذر ۱۳۹۷

    ممنون از پاسخگویی . پس اگر مقدور بود یا در انتهای همین پست یا پست جدید در رابطه با openssl_encrypt هم آموزشی قرار بدین

    پاسخ
    1. حسن شفیعی ۵ آذر ۱۳۹۷

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

      پاسخ
  8. محمد جواد ۵ آذر ۱۳۹۷

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

    پاسخ
    1. حسن شفیعی ۵ آذر ۱۳۹۷

      سلام. تابع mcrypt_encrypt منقضی شده و دیگر در ورژن های جدید php استفاده نمیشه و به جاش میتونید از openssl_encrypt بهره ببرید.
      base64_encode هم یک تابع با قابلیت برگشتی به حالت قبل و بسیار ساده است و معمولا برای اینکه رشته های عجیب و غریب رو نبینیم از تابع بهره می بریم.
      موفق باشید.

      پاسخ
  9. علی یعقوبی ۱ مرداد ۱۳۹۷

    سلام من میخواستم که کاربر بعد از اینکه صفحه وب رو سیو کرد با استفاده از Ctrl + S یک محتویات بهش اضافه بهش مثلا صفحه دیگه کار نکنه و رفرش خودکار بشه!

    ممنون میشم جواب رو به ایمیلم ارسال کنید

    با تشکر

    پاسخ
    1. حسن شفیعی ۱ مرداد ۱۳۹۷

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

      از keyCode ها در جاوااسکریپت استفاده کنید که در صورتی که کلید های ctrl یا s زده شده دستور document.body.innerHTML = “خطا خطا خطا”; را اجرا کنید تا کل محتویات صفحه پاک بشه.

      موفق باشید.

      پاسخ
  10. soroosh ۲۶ تیر ۱۳۹۷

    سلام ممنون از مقاله هاي خوبتون،شما اول مقاله گفتيد md5 يا hash امنيت كمتري دارن!پس چرا توصيه كردين از اينا استفاده كنيم؟!

    پاسخ
    1. حسن شفیعی ۲۶ تیر ۱۳۹۷

      سلام . خوشحالم که مفید واقع شده . بله و فقط برای جلوگیری از لو رفتن رمزعبورهای شما حتی با هک شدن دیتابیس به روش هایی مثل sql injection توصیه شده ,حتما از رمزنگاری ها استفاده کنید. که خب فرقی نداره میتونید از روش های دیگه هم استفاده کنید و فقط مقصود این بود که توصیه کنیم که به هیچ وجه رمزعبور ها رو بصورت متن ساده (plain text) استفاده کنید. حالا فرقی ندارد از چه الگوریتمی بهره می برید در هر حال امنیت این روش ها همیشه نسبت به متن ساده بیشتر است.

      موفق باشید.

      پاسخ
دوره های آموزشی

دانلود رایگان کتاب آموزش PHP

صفر تا صد PHP و MySQL را یکجا یاد بگیرید
همین الان دانلود کن
نگران نباشید. ایمیل‌های مزاحم نمی‌فرستیم
close-link