如何使用字节数组作为键对字符串进行XOR?

时间:2019-05-08 02:33:53

标签: java android encryption cryptography xor

我正在尝试使用XOR加密对String进行编码,并使用byte array作为密钥:

String encodedString = myString XOR myKey

我没有太多的密码学经验,所以我还没有找到实现这一目标的方法。

作为对该问题的更新,我发现myKey也是一个字符串,并且与myString的长度相同

2 个答案:

答案 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);
}