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.b4x.com/forum/basic4andr...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.b4x.com/forum/additional-libraries-official-updates/11430-licensing-library.html
 
Last edited:

Troberg

Well-Known Member
Licensed User
Longtime User
Two questions:

1. I can't find my public key. I'm on the web page with the test bench, but there is no key. Where is it?!?!

2. This thread is kind of long and messy, and, apparently, Google has a new method now. Is there thread that's more up to date? Some kind of summation of the current status?
 
Last edited:

Erel

B4X founder
Staff member
Licensed User
Longtime User
1. It should be under Services & APIs:

SS-2014-10-24_13.02.36.png


2. The new method doesn't require anything from the developer side.
 

Troberg

Well-Known Member
Licensed User
Longtime User
Thanks, found it. I was reading some earlier post, and was looking in the user account page. I didn't realize that they've moved it to a per app-basis.

Do I even need the key with the new method?
 

slugger

Member
Licensed User
Longtime User
Hi,

I am having a problem using this library.

My code is similar to the example given in the first page, the variable that is used in the SetVariableAndValue method has an underscore in it (it is called pub_extract).

If I declare the variables in the Process_Globals part of the main code everything runs fine.

If I move everything in the service module, declaring the variables in the Process_Globals part of the service, I get the following error:

B4X:
unexpected error.
java.lang.RuntimeException: java.lang.NoSuchFieldException: _pub_extract

Has anyone else experienced the same behavior?

Is the licensing library not to be used in services?
 

LucaMs

Expert
Licensed User
Longtime User
page which shows your publisher public key. This page also includes the "test console".

Sorry, I'm a newbie :D

I'm on a page that contains a "license key for this application"; I fear you was talking about a "publisher key", then a "personal" key, I suppose.
Also, in this page I cannot see the "test console".

I'm lost in Google pages!!!
 

incendio

Well-Known Member
Licensed User
Longtime User
I have this on manifest file : <uses-sdk android:minSdkVersion="4" />

Is this licensing library still works with sdk ver 4?
 

Eumel

Active Member
Licensed User
Longtime User
Look at the developer console left side.
There is a point where you put your developer name, adress and so on ..
In german it calls "Einstellungen".

There is a part "Lizenztest". Here you can put gmail adresses as testaccounts (max. 400)

-----------
Eumel
 

incendio

Well-Known Member
Licensed User
Longtime User
Found it!

Set test gmail account, but still got response Don't allow.
 

incendio

Well-Known Member
Licensed User
Longtime User
Update :
My Device has a firewall app that blocked the test license app.

After firewall disable, got error : NOT_MARKED_MANAGED, what does it means?

On developer console under License Test Response, tried RESPOND_NORMALLY & LICENSED, always return with error/ sub lc_Error called.
 
Last edited:

incendio

Well-Known Member
Licensed User
Longtime 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
Longtime 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
Longtime 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?
 
Top