Simply XOR encrypt in Javascript and Decrypt in Java

19,383

When XOR-encoding two strings, the resulting XOR-values of the individual characters sometimes do not result in characters that can be displayed. Therefore one solution is to encode the result as a sequence of hex-values and then to decode these hex-values on the server side.

Javascript:

function encryptStringWithXORtoHex(input,key) {
    var c = '';
    while (key.length < input.length) {
         key += key;
    }
    for(var i=0; i<input.length; i++) {
        var value1 = input[i].charCodeAt(0);
        var value2 = key[i].charCodeAt(0);

        var xorValue = value1 ^ value2;

        var xorValueAsHexString = xorValue.toString("16");

        if (xorValueAsHexString.length < 2) {
            xorValueAsHexString = "0" + xorValueAsHexString;
        }

        c += xorValueAsHexString;
    }
    return c;
}

Java-Code:

private static String decryptStringWithXORFromHex(String input,String key) {
    StringBuilder c = new StringBuilder();
    while (key.length() < input.length()/2) {
        key += key;
    }

    for (int i=0;i<input.length();i+=2) {
        String hexValueString = input.substring(i, i+2);
        int value1 = Integer.parseInt(hexValueString, 16);
        int value2 = key.charAt(i/2);

        int xorValue = value1 ^ value2;

        c.append(Character.toString((char) xorValue));

    }
    return c.toString();
};

Example: Encode in Javascript:

encryptStringWithXORtoHex('Encrypt This','SecretKey');

returns the string 160b00001c043f452d3b0c10

Decrypting in Java:

decryptStringWithXORFromHex("160b00001c043f452d3b0c10","SecretKey")

returns Encrypt This

Please note: the shown solution only works for characters that have a charChode value of less or equal than 255. If you want to use the solution for unicode characters (e.g. €) you will have to change the code to take care of this.

Share:
19,383
DragonGamer
Author by

DragonGamer

Nothing special here =(

Updated on June 18, 2022

Comments

  • DragonGamer
    DragonGamer almost 2 years

    The purpose for this is not highly security-relevant and the key will be long, so I'm just wanting to use simple XOR encryption to the strings.

    Well, the Javascript on the client is as follows:

    function dc_encrypt(str, key)
    {
       var ord = []; var res = "";
    
       var i;
       for (i = 1; i <= 255; i++) {ord[String.fromCharCode(i)] = i}
    
       for (i = 0; i < str.length; i++)
           res += String.fromCharCode(ord[str.substr(i, 1)] ^ ord[key.substr(i %    key.length, 1)]);
    
       return(res);
    }
    

    And the Java is is:

    public String dc_decrypt(String str, String key)
    {
       StringBuilder sb = new StringBuilder();
       for(int i = 0; i < str.length(); i++)
       sb.append((char)(str.charAt(i) ^ key.charAt(i % (key.length()))));
       return(sb.toString());
    }
    

    Unfortunately this produces some very weird results. Some letters differ after encrypting in JS, sending the result through a POST and decrypt in Java. In every case it doesn't seem to be reliable.

    I assume the issue must have something to do with encoding... does someone know a more reliable solution for this?

    Huge thanks in advance! :)