Android Tutorial Protect your Android application with the Licensing library

The licensing library allows you to use Android market licensing service to verify that the user is allowed to access your application.

Your applications sends a request to the local market application. The market application contacts the market server and returns the result. The result is cached based on the market rules.

It is recommended to go over Google's documentation related to the licensing method: Application Licensing | Android Developers

Configuring the licensing library is simple. You should first have a publisher account in the market.
The license key is available in Google Play developer console under Development tools - Services & APIs.

The licensing library and service will not prevent a dedicated hacker from hacking your application. It will however make it more difficult.

The first step is to initialize a LicenseChecker object:
B4X:
Sub Activity_Create(FirstTime As Boolean)
   Dim lc As LicenseChecker
   Dim p As PhoneId
   lc.Initialize("lc", p.GetDeviceId, publicKey, "kljdflkf".GetBytes("UTF8"))
   lc.SetVariableAndValue("test_1", "some secret value")
   lc.CheckAccess
End Sub
The result of the licensing check is cached locally. The cache is encrypted with AES algorithm. In order to avoid users from tampering with the cache and copying the cache to different devices, the device id is used together with the package name as the password.

Note that the same user will be able to download your application to other devices running with the same user account.

PhoneId (from the Phone library) requires the READ_STATE permission. The protection will still work if you pass an arbitrary string. It will be weaker however.
The Salt parameter should be an array of bytes with some random values (the values should be the same on each run).

Edit: It is recommended to use the alternative id method as described here: http://www.basic4ppc.com/forum/basi...oid-device-unique-id-alternative-phoneid.html

The next step is to call lc.CheckAccess. This in turn calls the market application or the local cache and checks whether the user is allowed to access the program.
One of the following events will be raised when the result arrives: Allow, DontAllow or Error (ErrorCode As String).
It is up to you to handle the event subs as required.

LicenseChecker.SetVariableAndValue
A simple way to hack an application is to "jump over" the checking code. For example a hacker might remove the call to CheckAccess and instead call your Allow event sub.
In order to make it a bit more complicated you can call LicenseChecker.SetVariableAndValue.
For example:
B4X:
lc.SetVariableAndValue("test_1", "some secret value")
The above code will set the value of a process global string value in the main activity named test1 to "some secret value" if the check was successful. You should not use or test the value of test1 in the Allow event sub as it will be too obvious. Instead you should use it later in your program.
You can be creative and pass the name of the variable or the value by using BytesToString or some other way.
As this variable is accessed in a dynamic way it will fail when the code is obfuscated. Therefore you need to include an underscore in the variable name to prevent it from being obfuscated. For example: test_1.
Note that SetVariableAndValue method will fail when running in rapid debug mode as the variable is part of the "debugger engine".

A more complete example:
B4X:
Sub Process_Globals
   Dim publicKey As String
   publicKey = "MIIBIjANBgkqhAADSFEFEFkiG9w0BfW/cGhTbtIs6QIDAQAB..."
   Dim test_1 As String
End Sub
Sub Globals

End Sub
Sub Activity_Create(FirstTime As Boolean)
   Dim lc As LicenseChecker
   Dim p As PhoneId
   lc.Initialize("lc", p.GetDeviceId, publicKey, "kljdflkf".GetBytes("UTF8"))
   lc.SetVariableAndValue("test1", "some secret value")
   lc.CheckAccess
End Sub
Sub lc_Allow
   Log("Allow")
End Sub
Sub lc_DontAllow
   Log("DontAllow")
   ToastMessageShow("Closing application.", True)
   Activity.Finish
End Sub
Sub lc_Error (ErrorCode As String)
   Log("error: " & ErrorCode)
   ToastMessageShow("Closing application.", True)
   Activity.Finish
End Sub
Sub Activity_Pause(UserClosed As Boolean)
 
End Sub
Sub Activity_Resume

End Sub

The library is available here: http://www.basic4ppc.com/forum/additional-libraries-official-updates/11430-licensing-library.html
 
Last edited:

incendio

Well-Known Member
Licensed User
From my experience the only reliable way to test it is by publishing the app and then optionally unpublish it.
So, by publishing it, I can test it if licensing is works or not.

This licensing server, is it effective right away after apk uploaded or should wait for some time?
 

Peter Simpson

Expert
Licensed User
The perfect tutorial as usual @Erel, thank you :)

As you mentioned on another post, developers can (should) replace GetDeviceId with GetSettings("android_id") because GetDeviceId does not return an ID on WiFi only device.

Replace this
B4X:
Dim p As PhoneId
lc.Initialize("lc", p.GetDeviceId, publicKey, "kljdflkf".GetBytes("UTF8"))
with this
B4X:
Dim Pho As Phone
lc.Initialize("lc", Pho.GetSettings("android_id"), publicKey, "kljdflkf".GetBytes("UTF8"))
 
Last edited:

incendio

Well-Known Member
Licensed User
I have published app, but still got error NOT_MARKET_MANAGED.

The app already published before doing a test license. I just took its license key and put it in the sample code from the first post, but it always return an error.

Did i miss something here?
 

incendio

Well-Known Member
Licensed User
Finally, I managed to made it worked.

Can we determine when users checked a license, it is checked from google server or from a cache?
 

incendio

Well-Known Member
Licensed User
How long this cache last? On my case, it I was only a few minutes.

Found out that Google used play strore app to connect or checked cached. Blocked this app & you will find that licensing is always return to Don't allow, even device has internet connection.

I suspect, different version of play store could behave differently.
 

incendio

Well-Known Member
Licensed User
I have another app on the same device, Trickster mod, this app also use licensing from Google, but its cached last for at least a week.

I wonder why my app's cached only last for a few minutes.
 

kepler

Active Member
Licensed User
Hi

A problem arised...

When we run the app for the first time to check the lib Offline we get an invalid licence - that can make some sense.

If we run it with the wifi on, the licence is checked and we're in.

But if we run it again Offline in a tablet we get again an invalid key.
In a cell phone, however, it will run AS LONG we don't clear the cache. If we clear the cache we get again an invalid licence... This is happening to me.

Does anyone has this issue? I'm running an alpha version for the time being - can that be the reason?

Kind regards,

Kepler
 

aidymp

Well-Known Member
Licensed User
Can you confirm if this library/Method is still current as a client has asked about implementing this!

Thanks

Aidy
 
Top