حسین کعبی: وقتی فیگو را در جام جهانی زدم....
برنامههای نوشته شده در جاوا بهدلیل استفاده از واسط زمان اجرای Java Runtime Environment یا بهطور اختصار JRE برای مهیا کردن بستری مناسب برای جلوگیری از کامپایل مجدد کد منبع و همچنین حفظ قابلیت جابهجایی و استفاده در پلتفرمهای مختلف، پس از کامپایل بهجای تبدیل شدن به زبان ماشین یا همان «صفر» و «یک» به قالب خاصی از دادهها بهنام Byte Code تبدیل میشود که این خروجی همان قالب قابل فهم و اجرا برای JRE است.
همین موضوع باعث میشود کد برنامههای نوشته شده به زبان جاوا را با استفاده از متدهای مهندسی معکوس تا حدود زیادی بازیابی کرد. این مشکل بهحدی جدی است که شرکت توسعهدهنده زبان جاوا یعنی سانمیکروسیستمز، اقدام به ارائه ابزاری بهنام Obfuscator برای مبهمسازی کد منبع نوشته شده از طریق تزریق کدهای اضافی بهزبان جاوا کرده تا پس از انجام عملیات دیکامپایل، کاربران نتوانند بهراحتی قطعات مختلف کد حاصل را درک و تفسیر کنند.
اجرای این برنامه بهگونهای است که در بدنه توابع و کلاسها در نتیجه نهایی و خروجی اصلی برنامه تغییری را در پی نخواهد داشت. البته استفاده از این متد که بهصورت توکار (یا درونساخت Built-in) هم در کتابخانههای جاوا و هم توسط IDE پیشفرض شرکت سان، یعنی Netbeans نیز پشتیبانی میشود، نمیتواند تمام آنچه که برنامهنویسان برای ایجاد امنیت بیشتر به آن نیاز دارند را تامین کند. گذشته از این، استفاده از روش مذکور سبب افزایش حجم فایل اجرایی پس از کامپایل، کندی در بارگذاری و اجرای برنامه، سختتر شدن انجام عملیات اشکالزدایی (دیباگ)، بالا بردن میزان استفاده از حافظه اصلی و تحمیل بار مضاعف بر دوش پردازنده بهدلیل استفاده مکرر از حلقههای تکرار و تصمیمگیری میشود.
در این میان روشی کاملا ابتکاری توسط برخی برنامهنویسان برای هر چه بالاتر بردن ضریب امنیت در کدهای جاوا یا حتی دیگر زبانهای برنامهنویسی که از یک قالب همسان با فریمورک جاوا بهره میبرند، ارائه شده است. این روش که به متد رمزگذاری (Encryption) معروف است، هماکنون بهعنوان یکی از بهترین و موثرترین راهحلهای مطرحشده برای حفاظت از کدهای جاوا شناخته میشود. تفاوت عمده این روش با دیگر متدها در این است که روش رمزگذاری از آغاز تا پایان باید توسط برنامهنویس و گروه توسعهدهنده پروژه پیادهسازی شود؛ برخلاف روش Obfuscator که برای مبهم کردن کد منبع از الگوهای محدود و تکراری استفاده میکند.
شاید این موضوع در نگاه اول کمی دشوار بهنظر برسد اما کارایی واقعی روش رمزگذاری به این موضوع وابسته است که منطق رمزنگاری در برنامه شما میتواند کاملا متفاوت با تصور دیگران یا بهعبارت دیگر کاملا ابتکاری و شخصی باشد.
رفتار متد رمزگذاری
در این روش فرض بر این است که تمام یا تعدادی از کلاسهای نوشته شده، بهجز کلاس اصلی پروژه و کلاسی که قرار است عملیات کدبرداری دیگر کلاسها را انجام دهد، با استفاده از یک برنامه واسط و یک کلید اصلی به مجموعهای از کاراکترهای غیرقابل فهم و نامفهوم تبدیل شده است. سپس کلاسهای کدشده در مسیر مناسب به پروژه افزوده میشوند.
کلاس اصلی پروژه باید بتواند با استفاده از توابعی که برای رمزگشایی کلاسهای کدشده توسط برنامهنویس طراحی شدهاند، کلاسهای مذکور را در حافظه دیکد و بازسازی کند تا در محل و زمان مناسب فراخوانی و استفاده شوند. به این ترتیب حتی بعد از دیکامپایل شدن برنامه نیز کاربران با انبوهی از کلاسهای رمزگذاری شده و کاراکترهای غیرقابل فهم روبهرو خواهند شد.
نحوه پیادهسازی
پیش از هر چیز باید گفت که بهترین حالت ممکن برای پیادهسازی روش رمزگذاری، زمانی است که تمام برنامهنویسیهای مربوط به کلاسها و متدهایشان بهصورت کامل انجام شده و پروژه آماده کامپایل شدن نهایی باشد. همانطور که پیشتر نیز گفته شد، برای پیادهسازی این متد ما نیاز به یک برنامه واسط برای رمزنگاری کلاسهای مورد نظرمان با استفاده از یک کلید اصلی و بر اساس الگویی که برنامهنویس مشخص کرده است داریم. برای نمونه، برنامه سادهای بنویسید که تمام کاراکترهای یک فایل از نوع کلاس جاوا را بهعنوان ورودی دریافت کرده و با یک مقدار بهعنوان کلید اصلی XOR کند. سپس باید کلاس یا تابع مستقلی برای کدبرداری کلاسهای رمزگذاریشده با استفاده از همان کلید اصلی نوشته شود تا در هنگام اجرای برنامه بتوانیم با فراخوانی آن، کلاسهای کد شده را در حافظه رمزگشایی و دوبارهسازی کنیم و سرانجام برنامه بدون هیچ مشکلی بتواند اجرا شود. توجه داشته باشید که کلید اصلی بهعنوان یک عنصر حیاتی برای حفظ امنیت و حتی ضامن اجرای صحیح برنامه، میتواند برای هر کلاس بهصورت متفاوت تولید شود یا از مجموعه چند عملیات پیچیده ریاضی روی مقادیر گوناگون بهدست آمده باشد، یا حتی روی یک قفل سختافزاری ذخیره شود تا برنامه بدون وجود آن اصلا اجرا هم نشود.
برای پنهان ماندن الگوریتم کدبرداری کلاسها نیز میتوانید از فایلهای کتابخانهای پویا و استاندارد (برای ویندوز پسوند dll و برای گنولینوکس پسوند so) نوشتهشده با زبان C استفاده کنید. البته در این حالت پیادهسازی الگوریتم رمزگشایی باید در همین کتابخانهها انجام شود و همینطور برای حفظ قابلیت اجرا و انتقال روی سایر پلتفرمها نیز باید کتابخانههای مورد نیاز و قابل استفاده روی سایر پلتفرمها را هم ایجاد کرده و همراه با دیگر منابع به پروژه بیفزایید تا بتوانید با توجه به نوع سیستمعامل، فایل کتابخانه مورد نظر را بارگذاری کرده و توابع مورد نیاز برای رمزگشایی را از داخل این فایلها فراخوانی کنید.
نتیجهگیری
روش یا متد رمزگذاری راهحل مناسبی برای حفظ امنیت کد برنامههای نوشته شده به زبان جاواست که بر خلاف دیگر روشهای معمول در روند عادی اجرای برنامه خللی وارد نمیکند و در صورتی که بهدرستی پیادهسازی شود حتی میتوان با اتکا به آن از فریمورک جاوا، بدون ترس از دیکامپایل شدن برنامه در پروژههای تجاری بزرگ و مستقل از سکو نیز استفاده کرد و با خیال راحت از مواهب بسیار زیاد جاوا برخوردار شد.
منابع
http://java.sun.com
http://www.javaworld.com
محمد جواد احمدی
حسین کعبی: وقتی فیگو را در جام جهانی زدم....