google developer day 2010 japan: マーケットライセンシングを使って android...
DESCRIPTION
本セッションでは、Android Market で提供されているライセンスサービスを紹介します。 最初にサービス概要を紹介したあと、Android アプリケーションにこのサービスをどのようにして設定し、統合し、そしてテストするかを解説します。さらに、このライセンスの実装をより安全にするためのいくつかのヒントを解説します。TRANSCRIPT
Android Market Licensing Tony Chan
Agenda • What is Market Licensing?
• Architecture
• Tips for securing your Market Licensing implementation
• How to get started?
What is Market Licensing?
Tell you whether a user is licensed to use your application
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
Architecture
Google License Server
Your App
LVL
Market App
Architecture
Bind
Signed License Status
User & App Data
User Info Android Phone
Retrieve
Tips for securing your Market Licensing implementation
Is my app secure after adding Market Licensing EXACTLY like the sample code?
NO! いいえ!
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)
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
Code Obfuscation
12
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
ProGuard
13
• 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
Modify the LVL code
14
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
Core LVL logic
15
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
Core LVL logic
16
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:
Core LVL logic
17
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
Entry/exit points of the LVL
18
• 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);...
Proper license check and response handling
19
• 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
Make your App Tamper-resistant
20
• 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
Offload license validation to a trusted server
21
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
Summary
22
• 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!
How to get started?
Signup Setup Integrate Test
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
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
SDK API 8 (revision 2) or above, with Google APIs add-on
Signup Setup Integrate Test
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
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
Download LVL
Signup Setup Integrate Test
Setup LVL • Move the library and the sample source code to a
new location (e.g. your Eclipse workspace)
Signup Setup Integrate Test
Setup LVL • Import the LVL as an Android library project
Signup Setup Integrate Test
ADT Plug-in • Check your current plug-in
Need new ADT if this is missing Signup Setup Integrate Test
ADT Plug-in • Version 0.9.7 or above • https://dl-ssl.google.com/android/eclipse/
Signup Setup Integrate Test
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
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
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
Test Environment
Signup Setup Integrate Test
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
Resources
40
• Market Licensing developer guide – http://developer.android.com/guide/publishing/
licensing.html
• Market Licensing 3-part series blog posts – http://android-developers.blogspot.com/2010/08/
licensing-server-news.html – http://android-developers.blogspot.com/2010/09/
securing-android-lvl-applications.html – http://android-developers.blogspot.com/2010/09/
proguard-android-and-licensing-server.html
Resources
41
• LVL issue tracker – http://code.google.com/p/marketlicensing/issues/
• Development and testing issues – http://groups.google.com/group/android-developers – http://stackoverflow.com/questions/tagged/android
• Accounts, publishing, and deployment issues – http://www.google.com/support/forum/p/Android+Market – http://market.android.com/support/bin/answer.py?
answer=186113