I’m trying to convert an Integer to a String, and then encrypt the String with a XOR encryption. But when i’m decrypting my Strin again, i get a different answer, that the String i typed before the encryption, and i don’t know what i’m doing wrong?
public class Krypte {
public static void main (String [] args) {
int i = 12345;
String k = Integer.toString(i);
String G = secure(k.getBytes());
System.out.println("Encrypted: " + G);
String U = secure(G.getBytes());
System.out.println("Decrypted: " + U);
int X = Integer.parseInt(U);
System.out.println("As an int: " + X);
}
public static String secure(byte[] msg) {
// Variables
int outLength = msg.length;
byte secret = (byte) 0xAC; // same as 10101100b (Key)
// XOR kryptering
for (int i = 0; i < outLength; i++) {
// encrypting each byte with XOR (^)
msg[i] = (byte) (msg[i] ^ secret);
}
return new String(msg);
}
}
There’s a subtle (yet very important) difference between
charandbytetypes. Consider this:This works (proof), because XORing some character value with a byte will (most probably) give you a valid character.
Not let’s see what happens in the original snippet – by adding this debugging output into the main loop of
securemethod:And the output would be:
It’s quite ok: first
getBytesfunction encoded the string given into an array of bytes using the platform’s default charset. Character'1'gets encoded into49byte value;'2'becomes50, etc.Then we’re XORing these values with our key – and get this sequence of bytes:
The final step seems easy: we just make (and return) a new String from this sequence of bytes, what can go wrong here? But in fact it’s the very step where, well, the fan get hit. )
See,
Stringconstructor tries to process this sequence of bytes using the platform’s default charset. Indeed, for some charsets these bytes represent a sequence of valid characters just fine – but not for UTF-8!…You probably already guessed what happens next. For each ‘undecodable’ sequence of bytes, as described here, the first byte is transformed into so-called Replacement character, and others are retried. In this particular example there would be five of these signs of failure in the string returned by the first
secureinvokation.Decoding this string is, well, quite meaningless – as it doesn’t store any information (except length) about the target string. That’s why the original code ultimately failed.