【问题标题】:How to XOR a String using a byte array as key?如何使用字节数组作为键对字符串进行异或?
【发布时间】:2019-05-08 02:33:52
【问题描述】:

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

String encodedString = myString XOR myKey

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

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

【问题讨论】:

  • 键和字符串大小一样吗?我假设不是。此外,XOR 不是加密。
  • 不要在您提出问题后更改问题。在这种情况下,我可以改变我的答案,但我真的不应该这样做。两个字符串而不是字符串和字节数组的异或是不同的。现在,您的问题中完全缺少“键”一词……回滚到以前的编辑。始终允许增强您的问题,但不允许更改其语义。
  • 不确定您尝试做什么,但在最后一次回滚时,您刚刚删除了 xor 标签 (?) 如果您愿意,可以在问题末尾添加如果键是一个字符串;毕竟我已经把它放在我的答案中了。
  • @MaartenBodewes 我真的很感谢你们所有的 cmets 帮助我改进。其实我还在努力理解我应该做些什么来解决这个问题
  • public static byte[] xorWithKey(byte[] a, byte[] key) { byte[] out = new byte[a.length]; for (int i = 0; i

标签: java android encryption cryptography xor


【解决方案1】:
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 将产生随机字节,因此您可能需要 base 64 编码(加密后)/解码(解密前)以获得密文字符串而不是字节数组。


我特意省略了执行此操作的代码,因为这是一个练习作业,祝您实现它的乐趣!

【讨论】:

  • 所以基本上我应该做的是 myString.getBytes();然后开始迭代 myKey 包含的字节?
  • 是的,就是这样。但是,您的索引最好从 0 到明文的大小(以字节为单位)而不是密钥 - 毕竟明文表示需要加密多少字节。
【解决方案2】:

终于明白了!

希望这对其他人有用。

这对我有用(2 个字符串内的异或):

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

【讨论】:

    猜你喜欢
    • 2021-05-05
    • 1970-01-01
    • 2019-12-17
    • 2020-02-14
    • 1970-01-01
    • 2021-09-24
    • 1970-01-01
    • 1970-01-01
    • 2022-08-21
    相关资源
    最近更新 更多