Собственный алгоритм RC4 дает неверный результат

Я написал следующую реализацию алгоритма RC4, где key — это структура RC4_KEY, как указано в Библиотека OpenSSL. m_key — это QByteArray, содержащий ключ set. Для этого теста я использовал «teste» в качестве ключа. Как видите, у меня есть еще два QByteArrays, один из которых содержит исходные (входные) данные, а другой — зашифрованные (выходные) данные.

void rc4SetKey() {
    for (int i = 0; i < 256; ++i) {
        key.data[i] = i;
    }
    for (int i = 0; i < 256; ++i) {
        int j = (j + key.data[i] + m_key[i % m_key.length()]) % 256;
        std::swap(key.data[i], key.data[j]);
    }
}

void rc4Encrypt(QByteArray &in, QByteArray &out) {
    out.clear();
    out.resize(in.length());
    for (int n = 0; n < in.length(); ++n) {
        int i = (i + 1) % 256;
        int j = (j + key.data[i]) % 256;
        std::swap(key.data[i], key.data[j]);
        int rand = key.data[(key.data[i] + key.data[j]) % 256];
        out[n] = rand ^ in[n];
    }
}

В целях тестирования я использую текстовый файл со следующими данными (в шестнадцатеричном формате):

31 32 33 34 35 36 37 38 38 39 31 30 0a

Используя онлайн-инструмент или функцию OpenSSL, я получаю следующий вывод (ключ: "teste" ):

6a 9d ae b6 17 61 7b 71 5f f7 46 f0 ab

Однако, используя мою собственную реализацию, я получаю следующее:

52 ec c2 b1 3d ca 6b 55 50 54 30 e7 ed

Я потратил довольно много времени и просмотрел различные псевдокоды или реализации, но я до сих пор не могу понять, где я ошибся.


person Veluria    schedule 06.05.2014    source источник


Ответы (1)


Это выражение (как в функциях set-key, так и в функциях шифрования) является недопустимым (компиляция со всеми включенными предупреждениями должна была указывать на это):

 int j = (j + ...

Помимо того, что это ерунда (попытка сослаться на значение переменной при ее инициализации), это не соответствует определению алгоритма - предполагается, что j объявляется вне цикла и не сбрасывается на каждой итерации.

Следующее должно исправить функцию набора ключей. Исправление для функции шифрования будет почти таким же (также необходимо исправить i таким же образом).

int j = 0;
for (int i = 0; i < 256; ++i) {
    j = (j + key.data[i] + m_key[i % m_key.length()]) % 256;
    std::swap(key.data[i], key.data[j]);
}
person nobody    schedule 06.05.2014