我正在尝试使用XOR加密对String进行编码,并使用byte array
作为密钥:
String encodedString = myString XOR myKey
我没有太多的密码学经验,所以我还没有找到实现这一目标的方法。
作为对该问题的更新,我发现myKey
也是一个字符串,并且与myString
的长度相同
答案 0 :(得分:2)
String encodedString = myString XOR myKey
这是不正确的。 Java中的字符串可以具有任何编码。字符串的编码是使用以字节为单位(即字节数组)的特定字符编码的表示。
所以您会这样做:
byte[] encodedString = myString.getBytes(StandardCharsets.UTF_8);
检索字节。
然后,您可以使用索引遍历encodedString
的字节。您将获得该字节在二进制密钥中的相同位置,并将这两个字节异或。可以将结果放入与encodedString
相同大小的新数组中。请注意,Java有点奇怪,因为您可能需要强制转换为字节值,即result[i] = (byte) xorResult
很常见,如果密钥中的字节用完,则必须再次将密钥中的索引重置为零。如果发生这种情况,您的加密方案将很容易受到攻击,因为一次性密码(OTP)是安全的,但是XOR密码肯定不是。
解密后(与加密相同),您可以使用以下方法取回字符串:
String myString = new String(encodedString, StandardCharsets.UTF_8);
很明显,如果这是一个字符串,则必须对密钥执行相同的操作。但是请注意,即使密钥在可打印字符上分布均匀,位值也可能 分布不均匀。换句话说,字符串作为XOR密钥使您容易受到密码分析,尤其是对位和字节的频率分析的影响。
XOR将产生随机字节,因此您可能需要基于64位编码(在加密之后)/解码(在解密之前)以获得密文字符串而不是字节数组。
我故意省略了执行此操作的代码,因为这是一项练习任务,请实现它很有趣!
答案 1 :(得分:0)
最后知道了!
希望这对其他人有用。
这对我有用(2个字符串内的XOR):
public static String xorHex(String a, String b) {
// TODO: Validation
char[] chars = new char[a.length()];
for (int i = 0; i < chars.length; i++) {
chars[i] = toHex(fromHex(a.charAt(i)) ^ fromHex(b.charAt(i)));
}
return new String(chars);
}
private static int fromHex(char c) {
if (c >= '0' && c <= '9') {
return c - '0';
}
if (c >= 'A' && c <= 'F') {
return c - 'A' + 10;
}
if (c >= 'a' && c <= 'f') {
return c - 'a' + 10;
}
throw new IllegalArgumentException();
}
private static char toHex(int nybble) {
if (nybble < 0 || nybble > 15) {
throw new IllegalArgumentException();
}
return "0123456789ABCDEF".charAt(nybble);
}