Dana Root
Dana Root

Reputation: 75

XOR two strings in JAVA

I'm trying to encrypt a string, part of it is to XOR the text with IV string. After having some difficulties I ended up in stackoverflow where a guy gave the following code:

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
import java.io.IOException;

public class StringXORer {

public String encode(String s, String key) {
    return base64Encode(xorWithKey(s.getBytes(), key.getBytes()));
}

public String decode(String s, String key) {
    return new String(xorWithKey(base64Decode(s), key.getBytes()));
}

private byte[] xorWithKey(byte[] a, byte[] key) {
    byte[] out = new byte[a.length];
    for (int i = 0; i < a.length; i++) {
        out[i] = (byte) (a[i] ^ key[i%key.length]);
    }
    return out;
}

private byte[] base64Decode(String s) {
    try {
        BASE64Decoder d = new BASE64Decoder();
        return d.decodeBuffer(s);
    } catch (IOException e) {throw new RuntimeException(e);}
}

private String base64Encode(byte[] bytes) {
    BASE64Encoder enc = new BASE64Encoder();
    return enc.encode(bytes).replaceAll("\\s", "");

}
}

It seemed to work except for 2 issues: The result string becomes longer. When tried to do XOR between "abcdefgh" and "abcdefgh" I got : "aaaaaaaaaaaa". Secondly, result of two identical strings becomes "aaaa...." - string of "a"s....

So the two questions are:

  1. Why is the resulted string becomes longer?
  2. Why the result of XOR between identical strings consists of list of "a"s...?

This is homework, appreciate any help.

Thanx!

Upvotes: 3

Views: 10294

Answers (1)

Christian Semrau
Christian Semrau

Reputation: 9013

The string gets longer because in addition to XORing it with the key, it is Base64 encoded.

Replace the call to base64Encode(...) with new String(...) and base64Decode(s) with s.getBytes() in order to get the original XORed String. But note that the encoded string will not look good when printed. A string XORed with itself will consist of \0 characters, which is printed as white space.

Even after that change, it is possible that getBytes() returns a byte array longer that the string length, depending on the platform default charset. E.g. UTF-8 will encode characters >= 128 as two or three bytes. Use ISO-8859-1 as a charset with 1-to-1 correspondence of characters <= 255 and bytes. Similarly, new String(...) might fail to produce the expected characters, because the given bytes are not valid for the platform default encoding.

Upvotes: 2

Related Questions