JavaScript Ninja – String Encryption, Easily!

  • Keeping some data in your JavaScript source, is unavoidable,
    it is best to keep it at-least, somewhat obfuscated.
  • Here is a simple string encrypt/decrypt function.
  • First run the function with your plain-text, to encrypt it.
    Next, store both the function and the encrypted text in your source-code.
    Need the plain-text again?
    Run the function again, but this time: on your encrypted text!
    to get the plain-text back.
  • The function is added to the String prototype for an easy access.
  • The Code:

    String.prototype.normalise_to_ascii   = function(){return unescape(encodeURIComponent(this)); }
    String.prototype.normalise_to_unicode = function(){return decodeURIComponent(escape(this));   }
    String.prototype.crypt_symmetric = function(key){
      var me = this + "";                                             //unlink reference
      key = Number(String(Number(key))) === key ? Number(key) : 13;   //optionaly provide key for symmetric-like-""encryption"".
      me = me.split('')                                               //to array of characters.
             .map(function(c){return c.charCodeAt(0);})               //to array of numbers (each is character's ASCII value)
             .map(function(i){return i ^ key;        })               //XOR ""ENCRYPTION""
      me = String.fromCharCode.apply(undefined, me);                  //one-liner trick: array-of-numbers to array-of-characters (ASCII value), join to single string. may result in buffer-overflow on long string!
      return me;
  • Examples:

    • "hello".crypt_symmetric();
      will result with ehaab.
    • "שָלוֹם".crypt_symmetric();
      will result with פֵבטִא.

    Optionally keep your characters in the ASCII range,
    by .normalise_to_ascii() and bring them back
    to Unicode using .normalise_to_unicode().

    The explanation “why it is required?” is a bit long,
    so it is up to you if it is needed or not.

    Basically, since XOR creates a little character-shift,
    You might end up with a “control-character”, that might make your code looks ugly,
    at this case you can always use "YOUR_STRING".crypt_symmetric().normalise_to_ascii() and btoa,
    to keep it as a BASE64 string,
    followed by atob and "YOUR_STRING".normalise_to_unicode().crypt_symmetric() to restore it :]

  • Yes. The same function acts as an ecryptor and as a decryptor.
    It uses a very simple symmetric-encryption using XOR and a key,
    which by default is 13, but you may, optionally, provide your own key (number).
  • You are provided with some-what longer function,
    to help you visualise the steps, and simplified your understanding.
    Feel free to modify, minify the base structure to make it more/less complex to your needs… :]

    • Best to keep it simple though.

also available on this gist:

A slightly minified version of the same, as above..

String.prototype.norm_to_ascii=function(){return unescape(encodeURIComponent(this))};
String.prototype.norm_to_unicode=function(){return decodeURIComponent(escape(this))};
String.prototype.crypt_sym=function(k){return String.fromCharCode.apply(undefined,this.split("").map(function(c){return c.charCodeAt(0)^(k||13)}))};

//do this manually
//get "fWx+fnpif2k="
//store "fWx+fnpif2k=" in your code along with those 3 functions above.
//when needed the value, run:
//get "password"

Continue reading