3.11 System info, FileSystem, Security and Encryption
3.11.1 System info
3.11.1.1 Retrieve an ID
Refer
to so1,
so2
and so3.
According to this article,
android.os.Build.SERIAL
should
be unique if it is available. From the article: Devices
without
telephony are required to report a unique device ID here; some phones
may do so also.
The
1st
link has summary of phone:
All
devices tested returned a value for
TelephonyManager.getDeviceId()
-
All GSM devices (all tested with a SIM) returned a value for
TelephonyManager.getSimSerialNumber()
-
All CDMA devices returned null for
getSimSerialNumber()
(as expected) -
All devices with a Google account added returned a value for
ANDROID_ID
-
All CDMA devices returned the same value (or derivation of the same value) for both
ANDROID_ID
andTelephonyManager.getDeviceId()
-- as long as a Google account has been added during setup. -
I did not yet have a chance to test GSM devices with no SIM, a GSM device with no Google account added, or any of the devices in airplane mode.
So
if you want something unique to the device itself,
TM.getDeviceId()
should
be sufficient. Obviously some users are more paranoid than others, so
it might be useful to hash 1 or more of these identifiers, so that
the string is still virtually unique to the device, but does not
explicitly identify the user's actual device. For example, using
String.hashCode()
,
combined with a UUID:final TelephonyManager tm = (TelephonyManager) getBaseContext().getSystemService(Context.TELEPHONY_SERVICE);
final String tmDevice, tmSerial, androidId;
tmDevice = "" + tm.
getDeviceId
();
tmSerial = "" + tm.
getSimSerialNumber
();
androidId=""+android.provider.Settings.Secure.getString(getContentResolver
()
,android.provider.Settings.
Secure.
ANDROID_ID
);
UUID deviceUuid = new UUID(androidId.hashCode(), ((long)tmDevice.hashCode() << 32) | tmSerial.hashCode());
String deviceId = deviceUuid.toString();
might
result in something like:
00000000-54b3-e7c7-0000-000046bffd97
3.11.2 Filesystem
/data/app:
apk files of all installed apps.
/data/app-lib:
package subfolder which contains libs
/data/data:
package subfolder which contains app files, include shared_prefs
3.11.3 Protect App source from decompiling: proguard
Refer
to hackernews
and this post
for security apps. For security programing, refer to android crypto
and this tutor.
My thought and learnt from other app: use JNI which cannot be easily
decompiled; rename class name to meaning-less; put in a lot of
redundant code to confuse decompiler; Use filesize info as usually
decompile and recompile will change the size significantly. To
protect Java code against decompiler, here is several links, SO,
Eclipse,
xda.
-
You can encrypt your classes with a private key, and use a custom classloader to decrypt your classes with a public key before loading into memory, but it is not too complex to modify the classloader to save onto a disc all the classes loaded.
-
You can try crash decompilers. JAD is one of the best decompilers but if you add corrupted entries in the constant pools, all products powered by JAD crash. However, some decompilers are still working.
The
only way to protect your software, is to deploy it in a SaaS/PaaS.
Refer this for IaaS,
PaaS and Saas: the
importance of applications in a virtualized environment has brought
about three major trends in cloud computing:
-
Infrastructure as a Service (IaaS): Used to manage low-level resources like VMs and disks. The end user is responsible for what is running within the VM, starting with the OS. IaaS is most closely related to a regular automated virtualized system. Amazon Web Services is maybe the best-known provider for an IaaS-style cloud service, but there are numerous others in the market.
-
Platform as a Service (PaaS): Provides faster development and deployment platforms by abstracting the user from the OS while adding well-defined APIs to many essential services (such as the Web, databases, mail, queues, and storage) that the developer must use. Both sides benefit; development should be faster and the end product should be more reliable more quickly. Typically PaaS also provides monitoring and administrative consoles tightly designed around the platform, making operations easier. At the same time, by maintaining tight control over what is executed when, PaaS can make better decisions about machine load, at least in theory. Another side effect is a vendor lock-in, desirable to the vendor but maybe not to the developer. Windows Azure is a good example of a PaaS-style cloud.
-
Software as a Service (SaaS): Instead of writing and maintaining every application, one uses online services. Examples include Google Mail and Salesforce. It is important to note that the SaaS software provided by a vendor might not be running in a cloud, but SaaS offerings often make sense when developing an application for the cloud. For instance, if I develop an e-commerce solution in the cloud, I might not want to reinvent my own load balancers, databases, or payment-processing system. I might not even want to run or operate them; perhaps all I want is to use these services. Using SaaS vendors allows me to concentrate on my own application.
Refer
this
for setting proguard
with Android Studio. Refer this SO
for enable proguard
in Eclipse/ADT project. So for Android
Studio, change
build.gradle
minifyEnabled
to true.
For Eclipse,
uncomment this line in project.properties
file:
proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
this
include one txt from SDK root(which has common
setting), and one in
the root of project folder(user
defined). Then right
mouse click the project=>Android
Tools=>Export
Signed/Unsigned
Application Package.
After, might need run zipalign,
as mentioned in 3.9.1, like:
~/android-sdks/build-tools/23.0.3/zipalign
-v 4 iFunTV.apk iFunTV_18.apk . After
that, use adb
install -r iFunTV_18.akp
to update.
If
got problem with ProGuard, follow instruction here
to get around it. Usually ignore warning for external jar: -dontwarn
org.apache.**
To
keep a particular package/class:
-keep
class javax.** { *; }
Keep |
From being removed or
renamed |
From being renamed |
---|---|---|
Classes and class members |
-keep |
-keepnames |
Class members only |
-keepclassmembers |
-keepclassmembernames |
Classes and class
members, if class members present |
-keepclasseswithmembers |
-keepclasseswithmembernames |
Note,
for example, if want to keep hdp.http.MyApp
=>public
static String
getTumd5(),
should put inside -keepclasseswithmembers
class
hdp.http.MyApp
either
'***
getTumd5()'
or 'public
static ** getTumd5()',
no 'String'.
Be
careful of code like UpdateInfo
apkInfo
= (UpdateInfo) gson.fromJson(jsontxt,
UpdateInfo.class),
have to keep the class. Refer to Gson
guide and SO.
Another problem is Gson with ArrayList. Refer to this SO
and this SO,
and Gson
Proguard rule.
The
popular algerithm is RSA
and AES.
Refer to this SO
for AES implementation for NDK: google
openssl, and just AES
implement.