User:Dan Bron/Temp/Unlock

From J Wiki
Jump to: navigation, search

Leigh,

First, it appears that locked scripts must be stored in a file. That is to say, you can't execute a locked script from a noun. I don't know why. Maybe the frontend unlocks the script. In any case, the documentation does not reflect this requirement and should be expanded [1] .

Second, be aware that the argument to 3!:6 is the __text__ to "encrypt", not a filename. So, if you're saying something like this:

   3!:6          'filename'

change it to this:

   3!:6 ] 1!:1 < 'filename'

Third, I quoted the word "encrypt" on purpose. Be aware that there is no way, even in theory, for a system to be able to automatically read a locked script but a human user not.

Encryption requires that the stakeholder hold a secret key and intervene when he wants to clear (make readable) the text. If J is clearing the script, without you (the stakeholder) entering a secret key every time, then J is holding that secret key. And if J is holding the key, and the user is holding J, then the user is holding the key. So anything J can do, the human user can duplicate.

Here is a concrete example of the problem:

   NB.  Create a locked script
   (3!:6 ] 0 : 0) 1!:2 fl =. < jpath '~temp\test.ijl'
secret =: sauce@:*
sauce =: +/
)


   NB.  Verify that the names don't exist yet...	
   nc ;: 'secret sauce'
_1 _1


   NB.  Load the locked script	
   0!:0 fl
	
   NB.  Verify that now they do...
   nc ;: 'secret sauce'
3 3

   NB.  Now, verify that the definitions of the names are hidden
   NB.  from prying eyes.
   secret
secret

   NB.  Seems pretty safe.	
   secret f.
secret

   NB.  Unlock:
   'secret' f.
sauce@:*

   NB.  That cheat won't do much good unless we know
   NB.  which names are locked, so:
   ] locked_names =: > {. 4!:5&.>i._2 [ 0!:0 fl  [ 4!:5&>i. 2
+-----------+------------+
|sauce_base_|secret_base_|
+-----------+------------+

   NB.  Voila
   (,. 3 : 'y f. 1 : ''5!:5 {.;:''''u'''' '' '&.> ) locked_names
+------------+--------+
|sauce_base_ |+/      |
+------------+--------+
|secret_base_|sauce@:*|
+------------+--------+

See [2] for comprehensive solution.

I want to stress that the exploit above isn't the problem, only an demonstration of it. Even if Roger "fixed" f. and 4!:5, other approaches are possible. For example, I could use 15!:6 and 15!:7. And if Roger made J impregnable through reflection, then, were I adept, I could run J through a disassembler, step through until I got to the section that "decrypts" 3!:6 style strings, and duplicate that logic in a separate utility. In fact, I'd wager that 3!:6 is just an encoder anyway (not an encrypter which uses, e.g., AES and stores the private key in the binary), and is vulnerable to commonplace attacks, particularly since anyone can convert plaintexts to locked texts for testing.

So, the questions you need to ask yourself are "how difficult should it be for a user to duplicate the clearing process?" and "how much is each additional layer of difficulty worth to me?".

And, bear in mind that J itself is a kind of encoding, and it is fairly difficult to "decrypt". Becoming adept enough at J to read your scripts is probably at least as difficult as becoming adept enough at disassembling to figure out 3!:6.

So, how likely is it that your clients will know or be able to learn enough J to be able to extend their license by modifying your script? If it's likely, then you can obfuscate your code. If you used lines like those below, THEN how likely would it be that your clients could "decrypt" it?

  temps  =.  (+0 _17 _3 _12 _20 _1 _16 _16 _78 _3 _16 _78 _4 _2 +117);(+100 +11 _3 11 21 0 10 16)
   'sufficient memory?' (](p:5)!:8)&29~ 36b1mp2>enthalpy~3{.6!:0$~0[".]>{.'entropy enthalpy'=.a.&i.^:_1:L: 0]59796160561 4641 A.&.> temps

-Dan

  1. The requirement should be mentioned at 0!:0 or 3!:6 or both.
  2. I've created script to unlock 3!:6 files and create a reasonable approximation of the original cleartext.

The fundamental principles are the same as the demonstration exploit, but the script handles all the edge conditions wrt parts of speech, explicit code, etc.

Here's an example (using the locked script created above):

> cd x:\path\to\j\root

> jconsole ~user\general\unlock.ijs ~temp\test.ijl > temp\test.ijs

> type temp\test.ijs
     sauce_base_ =:   +/
     secret_base_ =:   sauce@:*


Get the script here: unlock.ijs


Originally posted in the "Licensing/Controling J Applications" thread on the Forums.