View Full Version : یک سوال مربوط به امنیت اپلیکیشن
saeidd
یک شنبه 21 دی 1393, 18:31 عصر
سلام.
اگه در برنامه رشته ها رو بصورت عادی و داخل خود کد بکار ببریم، موقع دی کامپایل، عین همون رشته ها قابل مشاهده است؛ ولی وقتی رشته ها رو در فایل strings.xml تعریف کنیم، موقع دی کامپایل اون ها رو بصورت یه عدد نشون میده که فکر می کنم همون id شون باشه. حالا سوالم اینه که در حالت دوم، بازم اون رشته قابل کشفه؟ و میشه از همین id که نشون میده بهش رسید؟
و اینکه توصیه میشه که برای امنیت بیشتر رشته ها رو در زمان اجرا بسازیم این دقیقا یعنی چی؟ آیا همه ی رشته ها مد نظره؟
#root#
یک شنبه 21 دی 1393, 21:39 عصر
سلام.
اگه در برنامه رشته ها رو بصورت عادی و داخل خود کد بکار ببریم، موقع دی کامپایل، عین همون رشته ها قابل مشاهده است؛ ولی وقتی رشته ها رو در فایل strings.xml تعریف کنیم، موقع دی کامپایل اون ها رو بصورت یه عدد نشون میده که فکر می کنم همون id شون باشه. حالا سوالم اینه که در حالت دوم، بازم اون رشته قابل کشفه؟ و میشه از همین id که نشون میده بهش رسید؟
سلام
نمیدونم چجوری decompile کردید ولی اگه این طور بود اینهمه برنامه خارجی ترجمه شده به زبان فارسی در مارکت ها (بجز بازار) عرضه نمیشد. (عرضه > فروش)
saeidd
یک شنبه 21 دی 1393, 22:48 عصر
نمیدونم چجوری decompile کردید ولی اگه این طور بود اینهمه برنامه خارجی ترجمه شده به زبان فارسی در مارکت ها (بجز بازار) عرضه نمیشد. (عرضه > فروش)
من فقط از ProGuard برای بالا بردن امنیت برنامه ام استفاده کردم.
چجوری دی کامپایل کرنشم، با همون dex2jar که خودتون میدونید. ضمنا برنامه رو به همون سایتی که بصورت آنلاین دی کامپایل می کنه دادم و اون دی کامپایل کرد و فایلهایی که اون بهم داد هم همونطور بود.
حالا سوال اصلیم این بود که راه محافظت از رشته ها چیه؟
عکسهای ضمیمه رو هم ببینید.
skkhossein
دوشنبه 22 دی 1393, 00:10 صبح
چیزی که من توی سایت ها خوندم دیگه امکان دیکامپایل فایل های apk وجود نداره دقیقا نمیدونم اما فکر میکنم از ورژن 4 اندرویدبه بعد.
اون سایت که دیکامپایل میکنه هم تست کردم جواب نداد
روند دیکامپایل به صورته که فایل dex رو به jar تبدبل میکنم(تغییر نام نمیدیم اونو تبدیل میکنیم با dex2jar) فایل جار رو مثلا با jd-gui باز میکنیم تا سورس رو تحویل ما بده
تمامی این مراحل رو امتحان کردم نشد
حالا شما از چه راهی به سورس رسیدی واسم عجیبه؟از نسخه های پایین اندروید استفاده کردین؟
Nevercom
دوشنبه 22 دی 1393, 05:53 صبح
اندروید هنگام کامپایل فایل های xml رو کد می کنه، اما قابل بازگشت هست، با ابزارهایی مثل apktool. پس ریسورس های شما امنیتی نخواهند داشت.
ProGuard سورس کد شما (Java) رو در هم ریخته می کنه، یعنی بعنوان مثال متد Hello رو به a تعییر میده، در مجموع با به هم ریختن سورس، وقتی دیکامپایل بشه، سورس به همون شکلی که شما نوشتید نخواهد بود و درکش کمی سخت هست، اما باز هم میشه منطق کدها رو متوجه شد.
ProGuard رشته ها رو کد نمیکنه. برای اینکار راهکارهای متفاوتی وجود داره، یکی اینکه رشته های مهم رو با یک الگوریتم در Runtime بسازید، که باز هم مشکلش اینه که همون کد اگر استخراج بشه و خارج از برنامه اجرا بشه، رشته ی نهایی رو تولید می کنه.
ابزارهایی مثل DexGuard وجود دارن که اینکار رو مدیریت می کنن. اما رایگان نیستن
یک تاپیک در مورد Decompile در انجمن هست که توضیحات خوبی داره.
درنهایت به دلیل ماهیت زبان جاوا، هیچ امنیت ۱۰۰٪ وجودی نداره (درواقع هیچوقت امنیت ۱۰۰٪ وجود نداره، اما در زبان هایی مثل جاوا که سورس کد ها به ByteCode ترجمه میشن دست یابی به سورس راحت تر هست)
تمام تلاش ها به این سمت هست که سورس اونقدر درهم ریخته کنیم که وقتی هم دیکامپایل شد، زحمت زیادی داشته باشه تا بشه درکش کرد.
skkhossein
دوشنبه 22 دی 1393, 06:30 صبح
من هم حرف شما رو تایید میکنم یکی از ویژگی های جاوا اینه که سورس کامپایل شده قابل بازیابی هست و این ماهیت جاوا و برنامه های اپن سورس هست
اما گویا کم کم باید به سمتی پیش بریم که جلوی دیکامپایل برنامه گرفته بشه مانند همون برنامه ها و ابزار های جلوگیری از دیکامپایل که خودتون هم ذکر کردین
وتجربه ای که خودم نیز برای این کار داشتم(کار نکردن ابزار دیکامپایل و سایت مربوطه)
saeidd
دوشنبه 22 دی 1393, 06:31 صبح
چیزی که من توی سایت ها خوندم دیگه امکان دیکامپایل فایل های apk وجود نداره دقیقا نمیدونم اما فکر میکنم از ورژن 4 اندرویدبه بعد.
حالا شما از چه راهی به سورس رسیدی واسم عجیبه؟از نسخه های پایین اندروید استفاده کردین؟
اتفاقا از اندروید 4 به بالا استفاده کردم، با همون dex2jar
ProGuard رشته ها رو کد نمیکنه. برای اینکار راهکارهای متفاوتی وجود داره، یکی اینکه رشته های مهم رو با یک الگوریتم در Runtime بسازید، که باز هم مشکلش اینه که همون کد اگر استخراج بشه و خارج از برنامه اجرا بشه، رشته ی نهایی رو تولید می کنه.
دلیل اینکه رشته هایی که مستقیم تو کد نوشته میشن با رشته هایی که در strings.xml نوشته میشن، موقع دی کامپایل دو جور دیده میشن (عکسهای ضمیمه پست سوم) چیه؟
Nevercom
دوشنبه 22 دی 1393, 15:32 عصر
همونطور که میدونید اندروید فایل R.java رو خودش تولید می کنه که اشاره گرهایی برای ریسورس های مختلف برنامه درونش هست.
وقتی شما یک ریسورس به اپلیکیشن اضافه می کنید (مثلاً یک عکس در پوشه ی drawable یا یک رشته در فایل xml)، اول یک ID برای اون ریسورس در فایل R تولید میشه که باعث میشه شما بتونید از عبارتی مثل R.string.my_string برای اشاره به اون استفاده کنید.
شما یک عدد می بینید چون درواقع این فقط یک عدد هست، یک ID که بعد اندروید با استفاده از فایل R به یک ریسورس واقعی نسبتش میده.
اگر متد getString رو هم بررسی کنید، میبینید که پارامتر ورودی از نوع int دریافت می کنه.
saeidd
دوشنبه 22 دی 1393, 19:15 عصر
همونطور که میدونید اندروید فایل R.java رو خودش تولید می کنه که اشاره گرهایی برای ریسورس های مختلف برنامه درونش هست.
وقتی شما یک ریسورس به اپلیکیشن اضافه می کنید (مثلاً یک عکس در پوشه ی drawable یا یک رشته در فایل xml)، اول یک ID برای اون ریسورس در فایل R تولید میشه که باعث میشه شما بتونید از عبارتی مثل R.string.my_string برای اشاره به اون استفاده کنید.
شما یک عدد می بینید چون درواقع این فقط یک عدد هست، یک ID که بعد اندروید با استفاده از فایل R به یک ریسورس واقعی نسبتش میده.
اگر متد getString رو هم بررسی کنید، میبینید که پارامتر ورودی از نوع int دریافت می کنه.
درسته؛ حالا نکته اینه که وقتی از ProGuard استفاده می کنیم، موقع دی کامپایل دیگه فایل R دیده نمیشه و در نتیجه نمیشه فهمید عددی که پارامتر متد getString هستش به کدوم رشته داره اشاره می کنه. آیا راه دیگه ای برای کشف اون رشته هست؟
Amir Oveisi
دوشنبه 22 دی 1393, 22:16 عصر
اگر امنیت برنامتون خیلی مهمه براتون، بهترین شیوه این هست که بررسی های امنیتی رو آنلاین انجام بدید. کما اینکه اکثر برنامه های خارجی که امنیت توشون موضوع مهمی هست، برای لاگین شدن یا انجام یه سری کارها باید انلاین باشید.
برای برقراری امنیت رشته هاتون هم میتونید کل رشته ها رو با یه الگوریتمی مثل AES یا RSA رمز نگاری کنید و کلیدش رو توی سرورتون داشته باشید. این کلید برای هر کاربر منحصر به فرد باید باشه که اگر یک کاربر کلید رو بدست اورد برای بقیه کاربرها قابل استفاده نباشه. برنامتون در اولین اجرا کلید رو از سرور میگیره و رشته هاش رو رمزگشایی میکنه و به کاربر نمایش میده. کلید رو میتونید یه جایی از storage نگهداری کنید تا دفعات بعدی بتونید افلاین باهاش کار کنید اما این موضوع ضریب امنیت رو میاره پایین و بهترین حالت اینه که هر بار کلید رو از سرورتون دریافت کنید.
Nevercom
چهارشنبه 24 دی 1393, 17:35 عصر
درسته؛ حالا نکته اینه که وقتی از ProGuard استفاده می کنیم، موقع دی کامپایل دیگه فایل R دیده نمیشه و در نتیجه نمیشه فهمید عددی که پارامتر متد getString هستش به کدوم رشته داره اشاره می کنه. آیا راه دیگه ای برای کشف اون رشته هست؟
درواقع در بیشتر مواقع مشکل ما این نیست که کاربر بفهمه رشته ی ما کجا استفاده شده، بلکه نمیخوایم که به خود رشته دسترسی داشته باشه.
تمام فایل های xml که ریسورس ها هستند، به راحتی به فرمت XML استاندارد تبدیل میشن، یعنی تمام رشته هایی که در strings.xml ذخیره کردید در دسترس هست.
اگر امنیت برنامتون خیلی مهمه براتون، بهترین شیوه این هست که بررسی های امنیتی رو آنلاین انجام بدید. کما اینکه اکثر برنامه های خارجی که امنیت توشون موضوع مهمی هست، برای لاگین شدن یا انجام یه سری کارها باید انلاین باشید.
برای برقراری امنیت رشته هاتون هم میتونید کل رشته ها رو با یه الگوریتمی مثل AES یا RSA رمز نگاری کنید و کلیدش رو توی سرورتون داشته باشید. این کلید برای هر کاربر منحصر به فرد باید باشه که اگر یک کاربر کلید رو بدست اورد برای بقیه کاربرها قابل استفاده نباشه. برنامتون در اولین اجرا کلید رو از سرور میگیره و رشته هاش رو رمزگشایی میکنه و به کاربر نمایش میده. کلید رو میتونید یه جایی از storage نگهداری کنید تا دفعات بعدی بتونید افلاین باهاش کار کنید اما این موضوع ضریب امنیت رو میاره پایین و بهترین حالت اینه که هر بار کلید رو از سرورتون دریافت کنید.
میشه بیشتر توضیح بدید، چطور میتونیم داده هایی که با یک کلید خاص انکریپت شدن رو با کلیدهای متفاوت به ازای هر کاربر دیکریپت کنیم ؟
چون منطقاً تمام داده ها باید بصورت انکریپت شده در برنامه قرار داده بشن و در Runtime دیکریپت بشن.
saeidd
چهارشنبه 24 دی 1393, 17:54 عصر
درواقع در بیشتر مواقع مشکل ما این نیست که کاربر بفهمه رشته ی ما کجا استفاده شده، بلکه نمیخوایم که به خود رشته دسترسی داشته باشه.
تمام فایل های xml که ریسورس ها هستند، به راحتی به فرمت XML استاندارد تبدیل میشن، یعنی تمام رشته هایی که در strings.xml ذخیره کردید در دسترس هست.
این درسته که تمام رشته هایی که در strings.xml ذخیره شده در دسترس هست، ولی اگه ما رشته ها رو بصورت encrypt شده در strings.xml ذخیره کنیم، و در برنامه اونها رو decrypt کنیم و استفاده کنیم، اونوقت اگه کسی برنامه ما رو دی کامپایل کنه، رشته ها رو در strings.xml می بینه ولی چیزی نمی فهمه، و داخل کدهای برنامه هم فقط آی دی رشته ها رو می بینه. بنابراین اینجوری هم به رشته دسترسی نداره و هم نمی دونه کجای برنامه ازش استفاده شده، درسته؟
Nevercom
چهارشنبه 24 دی 1393, 18:04 عصر
اگر من بعنوان بخوام از برنامه ی شما سر در بیارم، متد دیکریپت کننده رو کپی می کنم، در یک حلقه رشته ها رو میدم به اون متد و دیکریپت شده ش رو تحویل میگیرم. کمتر از ۱۰ دقیقه از وقت من رو برای سردرآوردن از برنامه تون به خودش اختصاص میده.
saeidd
چهارشنبه 24 دی 1393, 18:32 عصر
اگر من بعنوان بخوام از برنامه ی شما سر در بیارم، متد دیکریپت کننده رو کپی می کنم، در یک حلقه رشته ها رو میدم به اون متد و دیکریپت شده ش رو تحویل میگیرم. کمتر از ۱۰ دقیقه از وقت من رو برای سردرآوردن از برنامه تون به خودش اختصاص میده.
خب اولا که متد دکریپت کننده، کدهاش بوسیله proguard به هم ریخته میشه و به این راحتی نمی شه ازش سر درآورد و ثانیا از الگوریتمهایی برای اینکریپت استفاده می کنیم که همراه رشته مون یه رشته دیگه به عنوان رمز بگیره که این رشته رمز رو هم میذاریم توی strings.xml؛ اون وقت کار خیلی سخت میشه.
بازم میشه به راحتی کشفش کرد؟
saeidpsl
چهارشنبه 24 دی 1393, 22:37 عصر
خب اولا که متد دکریپت کننده، کدهاش بوسیله proguard به هم ریخته میشه و به این راحتی نمی شه ازش سر درآورد و ثانیا از الگوریتمهایی برای اینکریپت استفاده می کنیم که همراه رشته مون یه رشته دیگه به عنوان رمز بگیره که این رشته رمز رو هم میذاریم توی strings.xml؛ اون وقت کار خیلی سخت میشه.
بازم میشه به راحتی کشفش کرد؟
با سلام
باید بگم proguard نمیتونه string رو بهم کنه برای مبهم کردن از این تاپیک (http://barnamenevis.org/showthread.php?460023-Decompile-And-Anti-Decompile&p=2059636&viewfull=1#post2059636) کمک بگیرید.
Nevercom
پنج شنبه 25 دی 1393, 02:35 صبح
خب اولا که متد دکریپت کننده، کدهاش بوسیله proguard به هم ریخته میشه و به این راحتی نمی شه ازش سر درآورد و ثانیا از الگوریتمهایی برای اینکریپت استفاده می کنیم که همراه رشته مون یه رشته دیگه به عنوان رمز بگیره که این رشته رمز رو هم میذاریم توی strings.xml؛ اون وقت کار خیلی سخت میشه.
بازم میشه به راحتی کشفش کرد؟
ابزارهای Obfuscator چند راه برای درهم کردن کدها بدون ایجاد اختلال در اجرای برنامه دارن.
یکی این هست که اسامی متدها و متغیرها رو تغییر بدن. مثلاً متدی دارید بنام sendMessage، این ابزار اگر نام این متد رو همه جا به a تغییر بده، تغییری در روند اجرای برنامه رخ نمیده و کد رو کمی درهم ریخته کرده (حتی کمی هم از حجمش کم کرده)، حالا این رو به تمام متد ها و متغیر ها و کلاس ها تعمیم بدید.
روش دیگه این هست که در Flow برنامه تغییر ایجاد کنن. مثلاً بیاد و ۱۰ تا متد الکی ایجاد کنه و کدهای اصلی رو بزاره تو این متد ها و متدها رو به ترتیب ایجاد کنه، حالا هرچی این سیستم هوشمند تر باشه، کدها رو بهتر میتونه درهم بریزه (و البته نباید Performance برنامه رو زیاد تحت تاثیر قرار بده).
حالا در مورد متدی که می فرمایید، فرض کنید متدی دارید بنام decryptMe که دو پارامتر میگیره، یکی رشته ی اصلی و دیگری کلیدی که برای دیکریپت مورد استفاده قرار میگیره.
حالا ProGuard میاد و اسم متد و متغیرها رو تغییر میده.
موضوع اینه که من اصلن نیاز نیست متد شما رو تحلیل کنم، کافیه همون متد با نام تغییر یافته رو کپی کنم و اجراش کنم.
حالا فرض می کنیم شما ۱۰۰۰ تا رشته دارید و نمیدونم کدوم کلید هست.
کافی هست در یک حلقه سعی کنم یک رشته ی انکریپت شده رو هربار با یکی از رشته ها بعنوان کلید دیکریپت کنم، در نهایت خیلی زود میتونم تشخیص بدم کدوم کلید هست.
و من راحت میتونم بفهمم که احتمالاً اون متد کارش دیکریپت کردن رشته ها هست، چون شما هرجا رشته ای دارید با این متد دیکریپتش می کنید و با کمی بررسی هویت اون متد مشخص میشه.
حرف من این هست که اگر رشته ای دارید که خیلی اهمیت داره، مثلاً یک کلید هست که اگر لو بره امنیت شما در سرویسی رو به خطر میندازه، این روش کارآمد نیست، یعنی امنیت رو فقط به اندازه ی ۲٪ افزایش میده (نسبت به زمانی که پروگارد تنها رو استفاده کردید).
اگر راهی باشه که امنیت به خارج از اپلیکیشن مثلاً به سرور انتقال پیدا کنه خیلی خیلی مطمئن تر هست.
یا مثلاً کلید برای انکریپت/دیکریپت کردن رو وابسته به خصیصه ای اپلیکیشن کنید که خارح از اپ در دسترس نباشه.
یا متد مربوط به دیکریپت رو در کلاس کامپایل شده ای بزارید و با Reflection بهش دسترسی پیدا کنید.
یا کتابخانه ای بصورت Native تهیه کنید و در کدها متد رو از اون کتابخانه صدا بزنید.
هیچ راه حل قطعی ای وجود نداره.
حالا سوال این هست که شما چقدر میخواید برای دست یابی به این امنیت وقت بزارید ؟ چقدر ارزشش رو داره ؟ چه چیزی رو قراره محافظت کنید ؟
پیشنهاد من این هست که اگر داده ی خیلی خیلی حساسی دارید سعی کنید تا حدی ایمن کنبد برنامه رو، انرژی تون رو صرف امنیتی که تضمینی روش نیست صرف نکنید.
vBulletin® v4.2.5, Copyright ©2000-1404, Jelsoft Enterprises Ltd.