Как XOR String, используя байтовый массив в качестве ключа? - PullRequest
1 голос
/ 08 мая 2019

Я пытаюсь закодировать строку с использованием шифрования XOR и использовать byte array в качестве ключа:

String encodedString = myString XOR myKey

У меня не слишком много опыта в криптографии, поэтому я не нашел способа достичь этого.

В качестве обновления этого вопроса я обнаружил, что myKey также является строкой и имеет ту же длину, что и myString

Ответы [ 2 ]

2 голосов
/ 08 мая 2019
String encodedString = myString XOR myKey

Это не правильно. Строка в Java может иметь любую кодировку. Кодировка строки - это представления, использующие определенную кодировку символов в байтах , то есть байтовый массив.

Так вы бы сделали:

byte[] encodedString = myString.getBytes(StandardCharsets.UTF_8);

для извлечения байтов.

Затем вы можете перебирать байты encodedString, используя индекс. Вы получите байт в том же месте в двоичном ключе и XOR два байта вместе. Результат может быть помещен в новый массив того же размера, что и encodedString. Обратите внимание, что Java немного странная в том смысле, что для этого может потребоваться приведение к байтовому значению, т.е. result[i] = (byte) xorResult

Как правило, вам придется снова обнулять индекс в ключе, если у вас кончились байты в ключе. Если это произойдет, ваша схема шифрования станет уязвимой для атаки, так как одноразовая клавиатура (OTP) безопасна, но шифр XOR, безусловно, нет.

После расшифровки, которая является той же самой операцией, что и шифрование, вы можете вернуть свою строку, используя:

String myString = new String(encodedString, StandardCharsets.UTF_8);

Очевидно, вам придется сделать то же самое для ключа, если это строка. Однако обратите внимание, что даже если ключ хорошо распределен по печатным символам, битовые значения скорее всего не хорошо распределены. Другими словами, строка в виде ключа XOR делает вас уязвимым для криптоанализа, в частности, анализа частоты битов и байтов.


XOR приведет к рандомизированным байтам, поэтому вам может потребоваться кодирование 64 (после шифрования) / декодирование (до расшифровки), чтобы получить строку зашифрованного текста, а не байтовый массив.


Я специально пропустил код для этого, так как это практическое задание, получайте удовольствие от его реализации!

0 голосов
/ 09 мая 2019

Наконец-то понял!

Надеюсь, это полезно для кого-то еще.

Это то, что сработало для меня (XOR в пределах 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);
}
...