Rich Jenks
Rich Jenks

Reputation: 1773

Simplest way to obfuscate and deobfuscate a string in JavaScript

I'm looking for a way to obfuscate and deobfuscate a string in JavaScript; by which I mean encryption and decryption when security is not an issue. Ideally something native to JS (like base64_encode() and base64_decode() in PHP) to "turn a string into something else and back again" without having to write a function.

Any suggestions welcome!

Upvotes: 69

Views: 75282

Answers (5)

Fighter178
Fighter178

Reputation: 413

A simple method to obfuscate a string is to use a script like this, using Node.js. This code is in Typescript.

import readline from 'readline';

const rl = readline.createInterface({
    input:process.stdin,
    output:process.stdout
});
const randNum = (max:number=10000)=>Math.floor(Math.random() * max);
// finds an equation that will make the target number.
const findEquation = (target:number)=>{
    let equation = "";
    const rand = randNum();
    const diff = target - rand;
    const rand2 = randNum()
    const product = diff * rand2;
    equation = `${rand}+(${product} / ${rand2})`;
    return equation;
}
const randCharSequence = (length:number)=>{
    let str = "";
    for(let i = 0; i < length; i++){
        str += String.fromCharCode(randNum(256));
    }
    return str
}
const sep = randCharSequence(8)
rl.question("Enter the string to obfuscate:\n", (str)=>{
    let obfuscated = "(''";
    str.split("").forEach(char=>{
        const code = findEquation(char.charCodeAt(0));
        obfuscated += `+(String.fromCharCode(${code})+\"${sep}\")`
    })
    obfuscated += `).split(\"${sep}\").join('')`;
    
    console.log("Obfuscated String:");
    console.log(obfuscated);
    rl.close();
});

When you run this script, you are prompted to enter the string to obfuscate. Then, the script prints out an obfuscated string. It uses equations that involve numbers of up to 10000 to generate numbers, that then get converted and concatonated into a string. But, that's not all. It adds a randomly generated string of 8 characters to the output, that gets removed when it is ran. This makes it harder to get a look at the string when reading the code, but keep in mind, that a person with access to the code, can easily add a console.log statement, and then get the string. Note, this isn't encryption, it just makes the code harder to understand and read.

Upvotes: 0

Tiago Rangel
Tiago Rangel

Reputation: 1328

1. Using strange strings

Go to http://www.jsfuck.com/, enter the input string, and get the result in the text box below.

Test this in the console and it will return "hi":

(+(+!+[]+[+[]]+[+!+[]]))[(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([]+[])[([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]][([][[]]+[])[+!+[]]+(![]+[])[+!+[]]+((+[])[([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]+[])[+!+[]+[+!+[]]]+(!![]+[])[!+[]+!+[]+!+[]]]](!+[]+!+[]+[+!+[]])[+!+[]]+([![]]+[][[]])[+!+[]+[+[]]]

console.log("Original: hi")
console.log("Converted: " + (+(+!+[]+[+[]]+[+!+[]]))[(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([]+[])[([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]][([][[]]+[])[+!+[]]+(![]+[])[+!+[]]+((+[])[([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]+[])[+!+[]+[+!+[]]]+(!![]+[])[!+[]+!+[]+!+[]]]](!+[]+!+[]+[+!+[]])[+!+[]]+([![]]+[][[]])[+!+[]+[+[]]])

It doesn't even look like a string!

2. Using atob and btoa

To use this method, just convert the string to base64 using atob("string") and then decrypt the string with btoa("encoded")

Upvotes: 3

Minko Gechev
Minko Gechev

Reputation: 25682

You can use btoa() and atob(). btoa() is like base64_encode() and atob() like base64_decode().

Here is an example:

btoa('Some text'); // U29tZSB0ZXh0
atob('U29tZSB0ZXh0'); // Some text

Keep in mind that this is not a secure way to keep secrets. Base64 is a binary-to-text encoding scheme that represents binary data in an ASCII string format by translating it into a radix-64 representation.

Upvotes: 108

Gant Laborde
Gant Laborde

Reputation: 6774

It's worth noting that

(![]+[])[+[]]+(![]+[])[+!+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]

evaluates to the string "fail" without ever looking like a string. Seriously, enter it into node and be amazed. You can spell anything in JavaScript by being crazy.

Upvotes: 47

enzian
enzian

Reputation: 1731

I'm obviously too late for an answer, but I was just working on another solution for the problem and base64 seemed to be to weak.

It works like this:

"abc;123!".obfs(13) // => "nopH>?@."
"nopH>?@.".defs(13) // => "abc;123!"

Code:

/**
 * Obfuscate a plaintext string with a simple rotation algorithm similar to
 * the rot13 cipher.
 * @param  {[type]} key rotation index between 0 and n
 * @param  {Number} n   maximum char that will be affected by the algorithm
 * @return {[type]}     obfuscated string
 */
String.prototype.obfs = function(key, n = 126) {
  // return String itself if the given parameters are invalid
  if (!(typeof(key) === 'number' && key % 1 === 0)
    || !(typeof(key) === 'number' && key % 1 === 0)) {
    return this.toString();
  }

  var chars = this.toString().split('');

  for (var i = 0; i < chars.length; i++) {
    var c = chars[i].charCodeAt(0);

    if (c <= n) {
      chars[i] = String.fromCharCode((chars[i].charCodeAt(0) + key) % n);
    }
  }

  return chars.join('');
};

/**
 * De-obfuscate an obfuscated string with the method above.
 * @param  {[type]} key rotation index between 0 and n
 * @param  {Number} n   same number that was used for obfuscation
 * @return {[type]}     plaintext string
 */
String.prototype.defs = function(key, n = 126) {
  // return String itself if the given parameters are invalid
  if (!(typeof(key) === 'number' && key % 1 === 0)
    || !(typeof(key) === 'number' && key % 1 === 0)) {
    return this.toString();
  }

  return this.toString().obfs(n - key);
};

Upvotes: 20

Related Questions