This is at present a proof of concept, but does allow applications written in B4J to be protected.
It relies on my Nashorn library.
The way it works is as follows:
The B4J application pulls in an AES encrypted javascript file from a source (disk or web).
It decodes it, and then allows for execution of functions held within.
If the incorrect key is used , the script file fails to decode and the application can handle the outcome.
Variables within the B4J application can be set from within the javascript (database credentials etc)
The interface between javascript and B4j is really simple.
The main protection comes from the fact the executable javascript only exists at runtime, so disassembling the program will not reveal the code in the javascript.
In the example attached, encryption and decryption is handled in the one app. Obviously you would not have the script encryption and decryption in the same application in a real world application.
I have used AES encryption, but it can be easily changed to any other supported encryption.
It relies on my Nashorn library.
The way it works is as follows:
The B4J application pulls in an AES encrypted javascript file from a source (disk or web).
It decodes it, and then allows for execution of functions held within.
If the incorrect key is used , the script file fails to decode and the application can handle the outcome.
Variables within the B4J application can be set from within the javascript (database credentials etc)
The interface between javascript and B4j is really simple.
The main protection comes from the fact the executable javascript only exists at runtime, so disassembling the program will not reveal the code in the javascript.
In the example attached, encryption and decryption is handled in the one app. Obviously you would not have the script encryption and decryption in the same application in a real world application.
B4X:
Sub Process_Globals
Private fx As JFX
Private MainForm As Form
Dim script As String
Dim nash As jInvokeNashorn
Dim enc As Cipher
Dim k As KeyGenerator
End Sub
Sub AppStart (Form1 As Form, Args() As String)
MainForm = Form1
'MainForm.RootPane.LoadLayout("Layout1") 'Load the layout file.
MainForm.Show
enc.Initialize("AES")
' make the script
script = $"
var b4j = Java.type("b4j.example.main") // this could be 'Me' passed from B4J
function test(){
print("hello from script")
b4j._hello() // this calls the sub hello directly from the script
}"$
' initialize the key this would be secret normally or passphrase
k.Initialize("AES")
k.KeyFromBytes("1234567890123456".GetBytes("utf8"))
' encrypt the script and save to disk
Dim eScript() As Byte = enc.Encrypt(script.GetBytes("utf8"),k.Key,False)
Dim out As OutputStream = File.OpenOutput("C:/temp","cipher.key",False)
out.WriteBytes(eScript,0,eScript.Length)
out.Flush
out.Close
' read the encrypted file and decode it
k.KeyFromBytes("1234567890123456".GetBytes("utf8")) ' try changing key here from correct one
Dim inp As InputStream = File.OpenInput("C:/temp","cipher.key")
Dim decodedScript(inp.BytesAvailable) As Byte
inp.ReadBytes(decodedScript,0,inp.BytesAvailable)
inp.Close
Try
Dim dString() As Byte = enc.Decrypt(decodedScript,k.Key,False)
' initialize nashorn on the script
nash.InitInvocable(BytesToString(dString,0,dString.Length,"utf8"))
' invoke the function in the script
nash.Invoke("test",Null)
Catch
Log("You are an invalid user and cannot access the full program")
End Try
End Sub
' just a sub called from the script
Sub hello()
Log("hello from main")
End Sub
I have used AES encryption, but it can be easily changed to any other supported encryption.