مخفی کردن داده‌های حساس

نویسنده : سید ایوب کوکبی ۳۰ خرداد ۱۳۹۸
مخفی کردن داده‌های حساس

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

استراتژی‌های مختلف در مخفی کردن داده‌های حساس:

  • قرار دادن داده‌ها در فایل strings.xml؛
  • پنهان کردن داده‌ها در سورس برنامه؛
  • مخفی کردن داده در BuildConfigs؛
  • استفاده از پروگارد؛
  • رمزنگاری و مبدل کردن رشته‌ها؛

برای درک بهتر توضیحات، مثال‌ها را می‌توانید از گیت‌هاب و نسخۀ دیکامپایل شدۀ آن دانلود و بررسی کنید.

مخفی کردن داده‌ها در فایل strings.xml

برنامه‌نویسان تازه‌وارد احتمالاً اولین جایی که سراغش می‌روند فایل strings.xml است. آن‌ها API Key، پسورد و داده‌های حساس را مثل عنوان اپلیکیشن در این فایل قرار می‌دهند؛ قافل از اینکه به راحتی آب خوردن می‌توان این داده‌ها را مشاهده کرد!

برای اینکه بفهمید چقدر این کار ساده است کافی است فایل apk را از گیت‌هاب دانلود کنید و با برنامه‌ای مثل Apk Studio محتویات این فایل را باز کرده و داده‌های حساس را بدون زحمت مشاهده کنید. پس این روش را کلاً فراموش کنید۱

مخفی کردن داده‌ها در سورس برنامه

راهکار بعدی، مخفی کردن کلید در متغیری استاتیک یا کمی سخت‌تر در یک آرایه از بایت‌هاست.

این بار نیز با مشاهدۀ محتویات فایل classes.dex – که نسخۀ کامپایل شدۀ برنامۀ جاوا است – می‌توانیم کلیدهای string و حتی آرایه‌ای از بایت‌ها را در آن بیابیم. در برنامه‌هایی مثل Apk Tools کار حتی ساده‌تر از این‌هاست چون دقیقاً برنامه را دیکامپایل می‌کند و متغیرها را به صورت مجزا در هر فایل نشان می‌دهد.

بخوانید  مهم‌ترین کلیدهای میانبر در اندروید استودیو

مخفی کردن داده‌ها در Build Config

راهکار بعدی، ذخیره کردن داده‌های حساس در BuildConfig پلاگین گریدل است. این استراتژی از این حیث که در کارهای تیمی داده‌های حساس را درون کدها فراموش نمی‌کنیم ارزشمند است چون به راحتی می‌توانیم این فایل را به gitignore. اضافه کنیم تا گیت از آن صرف نظر کند. ولی به هر حال در برنامه‌هایی که کلید را داخلِ خودِ برنامه ذخیره می‌کنند (مثلاً برنامه‌های آفلاین) چندان توفیقی حاصل نمی‌شود چون دقیقا به همان روش قبل از BuildConfig قابل استخراج است.

استفاده از پروگارد

گوگل توصیه کرده تا برنامه را قبل از انتشار با پروگارد Obfuscate کنیم. این ابزار با به هم ریختن کدها ضریب نفوذ به برنامه را کاهش می‌دهد. برنامه‌ای که با پروگارد به هم ریخته شده دیگر به سادگی نمی‌توان درک کرد. هکر نمی‌تواند منطق الگوریتم‌ها را خوب درک کند مگر زمان زیادی برای این کار بگذارد. ولی مشکل اساسی پروگارد این است که دست به رشته‌ها نمی‌زند.

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

کد اصلی
خروجی پروگارد

به هر حال گرچه پروگارد در سخت کردن نفوذ به برنامه نقش مهمی ایفا می‌کند و نام متغیرها، متدها، کلاس‌ها و سایر عناصر برنامه را در همی می‌آمیزد ولی همچنان نقش موثری در مخفی کردن رشته‌ها از چشمان نفوذگر ندارد. در واقع نسبت به روش‌های قبلی کار اندکی سخت می‌کند ولی نه آنقدر سخت که نتوان به رشته دست یافت.

مبهم‌سازی رشته‌ها

همانطور که دیدید پروگارد کاری به رشته‌ها ندارد. پس چرا خودمان این کار را انجام ندهیم. مثلاً با یک متد و الگوریتم مشخص، از یک رشتۀ به هم ریخته، رشتۀ واقعی را استخراج کنیم. از طرفی آن متد نیز با پروگارد به هم ریخته شده و نفوذگر به راحتی نمی‌تواند به الگوریتمش پی ببرد. مثلاً در مثال پایین متدی وجود دارد که با Xor کردن متوالی رشته این کار را انجام می‌دهد:

خوبی این روش این است که اگر برنامۀ شما خیلی اهمیت نداشته باشد کسی ساعت‌ها وقت خود را صرفِ استخراج منطق رمزگشایی و استخراج کلیدها نمی‌کند. ولی اگر برنامۀ شما پرمخاطب و مهم باشد (مثل ویندوز و فتوشاپ) قطعاً از دل کدهای دیکامپایل شده منطق رمزگشایی کشف و رشته شناسایی و استخراج می‌شود. با این حال امنیت این روش نسبت به روش‌های قبلی بسیار بیشتر است. به عنوان مثال الگوریتم بالا با مهندسی معکوس فایل smail توسط ApkTool قابل شناسایی است. همینکه عملگر Xor را ببینید نقشه لو می‌رود.

خلاصه

بهترین روش مخفی‌سازی داده‌ها، ذخیره کردنشان در سرور است. یعنی کلید را از طریق ارتباط با سروری که کاربر به آن دسترسی ندارد به برنامه ارسال کنیم. قطعاً مزیتش بیشتر و درصد نفوذ به برنامه هم کمتر ولی عیبش دردسر هزینه‌های اضافی سرور است. این کار شاید برای اپلیکیشن‌های سرور محور همچون پیام‌رسان‌ها معقول به نظر برسد ولی برای یک برنامۀ آفلاین که هیچ ارتباطی با سرور ندارد هزینۀ اضافه است.

بخوانید  آموزش زبان کاتلین – درس 6 (کامنت‌ها)

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

سید ایوب کوکبی

نویسنده و مترجم...

0 دیدگاه

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