我正在尝试将Integer转换为String,然后使用XOR加密对String进行加密。但是当我再次解密我的Strin时,我得到了一个不同的答案,即我在加密之前键入的字符串,我不知道我做错了什么?
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);
}
}
答案 0 :(得分:5)
char
和byte
类型之间存在微妙(但非常重要)的区别。考虑一下:
class Krypte {
public static void main (String [] args) {
int i = 12345;
String k = Integer.toString(i);
System.out.println("Before: " + k);
String G = secure(k.toCharArray());
System.out.println("Encrypted: " + G);
String U = secure(G.toCharArray());
System.out.println("Decrypted: " + U);
int X = Integer.parseInt(U);
System.out.println("As an int: " + X);
}
public static String secure(char[] 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 (^)
System.out.println("Byte before: " + msg[i]);
msg[i] = (char) (msg[i] ^ secret);
System.out.println("Byte after: " + msg[i]);
}
return new String(msg);
}
}
这有效(proof),因为对一个带有字节的字符值进行异或(most probably)会为您提供有效的字符。< / p>
不要让我们看看the original snippet中发生了什么 - 将此调试输出添加到secure
方法的主循环中:
System.out.println("Byte before: " + msg[i]);
msg[i] = (byte) (msg[i] ^ secret);
System.out.println("Byte after: " + msg[i]);
输出结果为:
Byte before: 49
Byte after: -99
Byte before: 50
Byte after: -98
Byte before: 51
Byte after: -97
Byte before: 52
Byte after: -104
Byte before: 53
Byte after: -103
没关系:首先getBytes
函数编码使用平台的默认字符集将字符串赋予字节数组。字符'1'
被编码为49
字节值; '2'
变为50
等等。
然后我们用我们的密钥对这些值进行异或 - 得到这个字节序列:
-99 -98 -97 -104 -103
最后一步似乎很简单:我们只是从这个字节序列中生成(并返回)一个新的String,这里可能出错?但事实上,这是风扇受到打击的最佳步骤。 )
请参阅String
构造函数尝试使用平台的默认字符集处理此字节序列。实际上,对于某些字符集,这些字节代表一系列有效字符就好了 - 但不适用于UTF-8!
......你可能已经猜到接下来会发生什么。对于每个'不可解码'字节序列,如described here,第一个字节将转换为所谓的Replacement character,其他字节将被重试。在这个特定的例子中,第一个secure
调用返回的字符串中有五个失败的迹象。
对此字符串进行解码很有意义 - 因为它不存储有关目标字符串的任何信息(长度除外)。这就是原始代码最终失败的原因。