3. Agenda
• What is Market Licensing?
• Architecture
• Tips for securing your Market
Licensing implementation
• How to get started?
4. What is Market Licensing?
Tell you whether a user is
licensed to use your application
5. Details…
• Protect your app on any devices that include
the Android Market app
• You maintain full control of how your app
enforces its licensing status
• Straightforward integration using the License
Verification Library (LVL). Any app with API
version 3 or higher can use this service.
• The service is free
9. Is my app secure after adding
Market Licensing EXACTLY like
the sample code?
NO!
いいえ!
10. Common Mistakes
• Used the sample code as-is
• Forgot to obfuscate the code
• Did not terminate their apps properly after
receiving a NOT_LICENSED response
• License validation logic was flawed (not
tested thoroughly)
11. Tips
Four areas to improve security:
• Code Obfuscation
• Modify the LVL code
• Make your application tamper-resistant
• Offload the license validation to a trusted
server
12. Code Obfuscation
1
responseCode -> k
checkAccess()->vw(); allow()->qb()
• Can:
– Remove symbols that reveal the original structure of a
compiled application
• Can’t:
– Prevent automated attacks
– Alter the flow of your program
• Obfuscator
– ProGuard
13. ProGuard
1
• Free, Open Source under GPL
• http://proguard.sourceforge.net
• Blog post
– http://android-developers.blogspot.com/2010/09/
proguard-android-and-licensing-server.html
• Helper Project at code.google.com
– android-proguard-commandline
– Require Android SDK Tools v7 or above
14. Modify the LVL code
1
The goal is to make your implementation
unique
Three areas to modify:
• Core LVL logic
• Entry/exit points of the LVL
• How your application invokes LVL and
handles license response
15. Core LVL logic
1
Two classes - LicenseChecker and LicenseValidator
• Replace switch statements with if statements.
• Use hash functions to derive new values for any
constants used
• Remove unused code
• Move all the LVL code into your own package
• Spawn additional threads to handle different parts of
the license validation
• Replace functions with inline code where possible
16. Core LVL logic
1
public void verify(PublicKey publicKey, int responseCode, String
signedData, String signature) {
// ... Response validation code omitted for brevity ...
switch (responseCode) {
// In bytecode, LICENSED will be converted to the
// constant 0x0
case LICENSED:
// NOT_LICENSED will be converted to the constant 0x1
case NOT_LICENSED:
handleResponse(LicenseResponse.NOT_LICENSED, data);
break;
// ... Extra response codes also removed for brevity ...
}
}
Original Sample code:
17. Core LVL logic
1
public void verify(PublicKey publicKey, int responseCode, String signedData,
String signature) {
// ... Response validation code omitted for brevity …
java.util.zip.CRC32 crc32 = new java.util.zip.CRC32();
crc32.update(responseCode);
int transformedResponseCode = crc32.getValue();
// crc32(LICENSED) == 3523407757
if (transformedResponseCode == 3523407757) {
LicenseResponse limiterResponse =
mDeviceLimiter.isDeviceAllowed(userId);
handleResponse(limiterResponse, data);
}
// ... put unrelated application code here ...
// crc32(NOT_LICENSED) == 2768625435
if (transformedResponseCode == 2768625435) {
userIsntLicensed();
}
}
Improved Sample code:
Use a hash function
to compute a new
response code value
Replace switch
statement with if
statements
Add unrelated code
to make it harder to
reverse engineer
18. Entry/exit points of the LVL
1
• Add additional arguments constructors and methods
• Remove Policy interface if no swappable policies
public LicenseChecker(Context context, Policy policy, String
encodedPublicKey, int nonce1, int nonce2)
...
public void allow(int nonce2);
...
public void dontAllow(int nonce1);
...
19. Proper license check and response handling
1
• Avoid putting license check code in onCreate() as
this method cannot be obfuscated
• Invoke a different activity rather than a dialog to
inform users about license failure
• Add additional finish() statements to make sure your
app is properly terminated when the user is not
licensed
• Set a timer thread that will handle license check
properly after a timeout
20. Make your App Tamper-resistant
2
• Add code to compare the current app’s signature with
the good known value (ideally from a server)
• Add code to compute the checksum of the current
app’s files and compare it with the good known
checksum (ideally from a server)
• Alter your code logic when your app is running in
debug mode
21. Offload license validation to a trusted server
2
Instead of doing the license validation on the Android
device, do it on a trusted server
• Pro:
– Very difficult to crack
– Can do more fine-grained license check (e.g. per
device)
• Con:
– Effective only if your app serves online content
– You have to maintain your own server
– Harder to implement
22. Summary
2
• Make your implementation is unique
• Change it often (e.g. every release)
• Make it difficult to trace when decompiled
• Make it resistant to any changes
Be creative!
25. Signup
• Android Market publisher account
• Have to use an existing account if you want to add
licensing support to your already published apps
• What you can do with the publisher account:
- Publish licensed and free apps
- Obtain the public key to decrypt license responses
- Test and debug licensing implementation
Signup Setup Integrate Test
26. Setup
• Download the latest SDK in order to debug your
implementation in the emulator
• Setup run-time environment
• Setup project configuration
• Download and setup the LVL
• (Optional) Download the latest ADT Plug-in if you
want to include the LVL as an Android library
project
Signup Setup Integrate Test
27. SDK
API 8 (revision 2) or above, with Google APIs add-on
Signup Setup Integrate Test
28. Setup Run-time Environment
• Device
- Running Android 1.5 or above
- Android Market app installed (should be
available in any compatible devices)
• Emulator (Android Virtual Device)
- Google APIs Add-On, API 8 (release 2) or above
- Add a Google account and sign in using your
publisher account or test account credentials
Signup Setup Integrate Test
29. Setup Project Configuration
No changes required if your project is using
API version 3 (Android 1.5) or above
Time to upgrade!!!
Signup Setup Integrate Test
31. Setup LVL
• Move the library and the sample source code to a
new location (e.g. your Eclipse workspace)
Signup Setup Integrate Test
32. Setup LVL
• Import the LVL as an Android library project
Signup Setup Integrate Test
33. ADT Plug-in
• Check your current plug-in
Need new ADT if this is missing
Signup Setup Integrate Test
34. ADT Plug-in
• Version 0.9.7 or above
• https://dl-ssl.google.com/android/eclipse/
Signup Setup Integrate Test
35. Integrate your app with LVL
Add the licensing permission to the application
manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" ...">
...
<!– Devices with SDK version 3 or above have version of Android
Market that supports licensing. -->
<uses-sdk android:minSdkVersion="3" />
<!-- Required permission to check licensing. -->
<uses-permission
android:name="com.android.vending.CHECK_LICENSE" />
...
</manifest>
Signup Setup Integrate Test
36. Integrate your app with LVL
Define a Policy
• Use one provided in the LVL
- ServerManagedPolicy (Recommended)
- Will cache license response and handle various conditions
- StrictPolicy
- License response must come from market license server
• Pre-defined policies do not fit your needs
- Implement the Policy interface
Signup Setup Integrate Test
37. Integrate your app with LVL
Signup Setup Integrate Test
• Add code to check license in your app’s main
activity
• (Optional) – Implement a DeviceLimiter
- Need to keep track of all the devices yourself
39. Test Environment
Signup Setup Integrate Test
Account Type Can check
license before
upload?
Can receive test
response?
Can set test
response?
Publisher Account Yes Yes Yes
Test Account No Yes No
Other No No No