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:

Highwinder

Active Member
Licensed User
Longtime User
Thank you!

I'd like to thank you for getting this library written. I have some concerns about the B4A community getting caught with pants down when Google gets around to cancelling their old Copy Protection service, which they've been promising for a while now.

THANK YOU for providing us with a way to use the new service! Whew!

Looking forward to putting it to use!

:sign0060:

- Highwinder
 

ondesic

Active Member
Licensed User
Longtime User
One thing to keep in mind when using this license is that google strongly suggests that you obfuscate your code with progaurd. Google's license can be cracked very easily article here

It would be nice to have an easy way from B4A to use progaurd.
 

ondesic

Active Member
Licensed User
Longtime User
It is in the planned feature list.

Note that the library itself is obfuscated and using SetVariableAndValue correctly should give you more protection.

I think google was talking about your entire code being obfuscated, not just the license library.

Anyway, thanks for the info. I am glad this is in the planned feature list.
 

magarcan

Active Member
Licensed User
Longtime User
So, does have Internet is needed in order to every time user execute our application??

Does B4A's Routing list is public??
 

Inman

Well-Known Member
Licensed User
Longtime User
No. The result is cached locally.

What will happen if the user

  • buys my app
  • runs it the first time and the Android Market license status get cached locally
  • then cancels the purchase and gets a refund within the allowed 15 minutes window
When he runs my app the next time and the license check is called, will it still return "Allow", based on the result data that is cached locally?
 

magarcan

Active Member
Licensed User
Longtime User
Using this library is the way, if you don't like people cheat you. I'll use this in my new releases.

Thanks!!!
 

peacemaker

Expert
Licensed User
Longtime User
So, if that copy protection works via Market application - at least for the first local permission info cashing - the Market must be internet conncted, isn't it ?
 

Highwinder

Active Member
Licensed User
Longtime User
Questions

Erel,

A few really horrible "Noob" questions about implementing the licensing lib:

1.)
lc.SetVariableAndValue("test1", "some secret value")

"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."

How do I "test the value"? In what way is it tested? Can you show an example? Is it simply something like "If test1 = TheSecretValue then licensecheck = passes.with.flying.colors"?

2.)
"lc.Initialize("lc", p.GetDeviceId, publicKey, "kljdflkf".GetBytes("UTF8"))"

Erel, what does the "kljdflkf" represent? I believe you called this a "Salt"? What is this and how is it used? Is length arbitrary or defined? Please elaborate.

3.)
"lc.SetVariableAndValue("test1", "some secret value")"

Can you please explain the "some secret value" part of that line? Is this supposed to be a number, letter, or otherwise random string of our choosing? Please elaborate for us "LCD noobs" who are sometimes a little slow at getting our heads around things. :)

And once again, THANK YOU for providing this functionality!

Highwinder the :sign0104:
 
Last edited:

Erel

B4X founder
Staff member
Licensed User
Longtime User
2) See this article for more information about salt: Salt (cryptography) - Wikipedia, the free encyclopedia
The string length is not really important.

1, 3) SetVariableAndValue is an optional feature which you can use to strengthen the protection.
A hacker can decompile your code, remove the CheckAccess call and compile it again. The hacked program will now work without doing any license check.
If however you did use SetVariableAndValue and CheckAccess is skipped then the variable value will not be set.
You should somewhere in your code do something with this variable which will fail if the variable was not set.

You should try to make it not too obvious. For example use the variable only further down the road. Instead of testing its value you can use its value. For example as the limiter of a For loop.
 

Kevin

Well-Known Member
Licensed User
Longtime User
I plan to implement this in my paid app soon, but just wanted to clarify something. From reading your tutorial as well as the info on the Android site, I assume that the library (or at least your sample code) uses the "Server Managed Policy" as opposed to a "Strict" or "Custom" policy?

I think for simplicity's sake I would prefer the managed policy, but I am curious which one we are actually using when using this library, and was also wondering if it would allow us to use the other policies if we wanted to.
 
Top