2011年3月25日 星期五

[LVL] Application Licensing

* Your applications can query Android Market at run time to obtain their licensing status for the current user, then allow or disallow further use as appropriate.

* Check License Flow:
  • An application checks the licensing status
  • The Market server signs the licensing status response using a key pair that is uniquely associated with the publisher account.
  • Your application stores the public key in its compiled .apk file and uses it to verify the licensing status response.

* In the licensing service
  • An application does not query the licensing server directly
  • But binding to a service provided by the Android Market application
  • Initiating a license check request calls the Android Market client over remote IPC to initiate a license request.
  • The Android Market service then handles the direct communication with the licensing server and finally routes the response back to your application.

* In the license request:
  1. The application: provides its package name and a nonce that is later used to validate any response from the server, as well as a callback over which the response can be returned asynchronously.
  2. The Android Market client: has greater permissions than the application, collects the necessary information about the user and the device (ex: the device's primary Google account username, IMSI, and other information) It then sends the license check request to the server on behalf of the application.
  3. The server:
    • Evaluates the request using all available information, attempting to establish the user's identity to a sufficient level of confidence.
    • Then checks the user identity against purchase records for the application and returns a license response, which the Android Market client returns to the application over the IPC callback.

* License responses secured through public key cryptography.
  • The server signs the license response data using an RSA key pair that is shared exclusively between the server and the application publisher.
  • The licensing service generates a single licensing key pair for each publisher account and exposes the public key in the account's profile page. (The publisher copies the public key and embeds it in the application source code, then compiles and publishes the .apk.)
  • The server retains the private key internally and uses it to sign license responses for applications published on that account.
  • When the application receives a signed response, it uses the embedded public key to verify the data. (The use of public key cryptography in the licensing service makes it possible for the application to detect responses that have been tampered with or that are spoofed.)


[LVL API]

* The key LVL interfaces are:
  • Policy: your implementation determines whether to allow access to the application
    • The implementation can evaluate the various fields of the license response and apply other constraints, if needed.
    • The implementation also lets you manage the handling of license checks that result in errors, such as network errors.
    • Declares two methods: allowAccess() and processServerResponse() which are called by a LicenseChecker instance when processing a response from the license server. It also declares an enum called LicenseResponse, which specifies the license response value passed in calls to processServerResponse().
  • LicenseCheckerCallback: your implementation manages access to the application
    • Based on the result of the Policy's handling of the license response.
    • Your implementation can manage access in any way needed, including displaying the license result in the UI or directing the user to purchase the application (if not currently licensed).

* ServerManagedPolicy
  • A flexible Policy that uses settings provided by the licensing server to manage response caching and access to the application while the device is offline (such as when the user is on an airplane).
  • Is highly recommended.

* Integrating the LVL with your application code involves these tasks:
  1. Adding the licensing permission your application's manifest.
  2. Implementing a Policy — you can choose one of the full implementations provided in the LVL or create your own.
  3. Implementing an Obfuscator, if your Policy will cache any license response data.
  4. Adding code to check the license in your application's main Activity
  5. Implementing a DeviceLimiter (optional and not recommended for most applications)

* AESObfuscator:
  • Provides secure obfuscation of data by using AES to encrypt and decrypt the data as it is written to or read from storage.
  • Seeds the encryption using three data fields provided by the application:
    • A salt: an array of random bytes to use for each (un)obfuscation.
    • An application identifier string, typically the package name of the application.
    • A device identifier string, derived from as many device-specific sources as possible, so as to make it as unique.

* To add the license check and handle the response, you must:
  1. Add imports
  2. Implement LicenseCheckerCallback as a private inner class
  3. Create a Handler for posting from LicenseCheckerCallback to the UI thread
  4. Instantiate LicenseChecker and LicenseCheckerCallback
  5. Call checkAccess() to initiate the license check
  6. Embed your public key for licensing
  7. Call your LicenseChecker's onDestroy() method to close IPC connections.

* A license check consists of two main actions:
  1. A call to a method to initiate the license check: in the LVL, this is a call to the checkAccess() method of a LicenseChecker object that you construct.
  2. A callback that returns the result of the license check: this is a LicenseCheckerCallback interface that you implement. The interface declares two methods, allow() and dontAllow(), which are invoked by the library based on to the result of the license check. You implement those two methods with whatever logic you need, to allow or disallow the user access to your application.

* During a license check, the LVL:
  • Passes the request to the Android Market application, which handles communication with the licensing server.
  • Passes the request over asynchronous IPC (using Binder) so the actual processing and network communication do not take place on a thread managed by your application.
  • Similarly, when the Android Market application receives the result, it invokes a callback method over IPC, which in turn executes in an IPC thread pool in your application's process.

* The LVL calls your LicenseCheckerCallback methods from the background thread.

* Note that LicenseChecker calls the LicenseCheckerCallback methods from the UI thread only if there is valid license response cached locally. If the license check is sent to the server, the callbacks always originate from the background thread, even for network errors.

* Finally, to let the LVL clean up before your application Context changes, add a call to the LicenseChecker's onDestroy() method from your Activity's onDestroy() implementation. The call causes the LicenseChecker to properly close any open IPC connection to the Android Market application's ILicensingService and removes any local references to the service and handler.


[Test]

* Setting up your environment for licensing involves these tasks:
  • Downloading the latest SDK, if you haven't already done so
  • Setting up the runtime environment for development
  • Downloading the Market Licensing component into your SDK
  • Setting up the Licensing Verification Library
  • Including the LVL library project in your application


* Reference
- Application Licensing

沒有留言:

張貼留言