2013-12-14 11 views
8

Я нашел следующую XOR функцию шифрования в Интернете:Как расшифровать шифрование простого XOR

void xor_encrypt(char *key, char *string) 
{ 
    int i, string_length = strlen(string); 
    for(i=0; i<string_length; i++) 
    { 
     string[i]=string[i]^key[i]; 
     printf("%i", string[i]); 
    } 
} 

Он отлично работает, но я хотел бы, чтобы расшифровать строку также.

Например:

void xor_decrypt(char *key, char *encrypted_string) 
{ 
    //decrypt method goes here 
} 

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

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

+2

Решите уравнение 'a = b^c' для' b'. –

+1

Ваша проблема заключается в том, как работает шифрование XOR, а не часть программирования. – Ray

ответ

12

Одна из замечательных особенностей шифрования XOR заключается в том, что при повторном применении дважды вы возвращаете исходную строку - см. http://en.wikipedia.org/wiki/XOR_cipher.

В вашей функции xor_decrypt вы берете строку и ключ и возвращаете строку^ключа. Если теперь вы снова или снова с ключом, вы получите (строка^ключ)^key = string^(key^key) = string^identity = строка (по свойствам оператора XOR: http://en.wikipedia.org/wiki/Exclusive_or#Properties)

, вы можете просто запустить вашу функцию xor_encrypt во второй раз на выходе первого xor_encrypt.

+2

до тех пор, пока символ ключа и соответствующий символ входной строки не будут такими же ... – Floris

+0

@floris - a^a == 0 и a^0 == a, поэтому утверждение все еще выполняется. (Повторное выполнение функции второй раз возвращает исходную строку.) –

+1

@MarcelPopescu - когда зашифрованная строка имеет в ней 0, это будет считаться окончанием файла (по функции, как указано выше), и дешифрование остановится , Вот почему я выступал (в своем ответе - под «предупреждение 1: пустые символы»), сохраняя исходную длину строки в переменной, а не полагаясь на 'strlen', которая будет неправильной для кодированной строки при keyChar == stringChar. Я поддерживаю то, что я сказал. – Floris

10

С XOR дешифрование - это точно такая же операция, как и шифрование. Запустите зашифрованную строку через метод xor_encrypt снова тот же ключ), и у вас есть обычный текст.

предупреждение 1: нулевые символы

Одна вещь, чтобы следить за: если символ в строке соответствует соответствующему символу в ключе, ваш результат будет '\0'. Это будет интерпретироваться вашим текущим кодом как «конец строки» и прекратит расшифровку. Чтобы обойти это, вы хотите передать длину «фактической» строки в качестве параметра вашей функции.

предупреждение 2: короткие ключи

Вы также хотите, чтобы убедиться, что вы не пробежать мимо конца ключа - если обычный текст очень долго вы, возможно, придется повторить ключ. Вы можете сделать это с помощью оператора % - просто переработайте ключ с самого начала.

Вот полный пример, который показывает эти методы:

#include <stdio.h> 
#include <string.h> 

void xor_encrypt(char *key, char *string, int n) 
{ 
    int i; 
    int keyLength = strlen(key); 
    for(i = 0 ; i < n ; i++) 
    { 
     string[i]=string[i]^key[i%keyLength]; 
    } 
} 

int main(void) { 
    char plain[] = "This is plain text"; 
    char key[] = "Abcdabcdabciabcdabcd"; 
    int n = strlen(plain); 
    // encrypt: 
    xor_encrypt(key, plain, n); 
    printf("encrypted string: \n"); 
    for(int ii = 0; ii < n; ii++) { 
    if(plain[ii] > 0x32 && plain[ii] < 0x7F) printf("%c", plain[ii]); 
    else printf(" 0x%02x ", plain[ii]); 
    } 
    printf("\n"); 
    // **** if you include this next line, things go wrong! 
    n = strlen(plain); 
    xor_encrypt(key, plain, n); 
    printf("after round trip, plain string is '%s'\n", plain); 
} 

Это (не понимая проблему с Kay == строкой) приводит к укороченному дешифрованию (The i в plain соответствует тем же буквам в key):

encrypted string: 
0x15 0x0a 0x0a 0x17 A 0x0b 0x10 D 0x11 0x0e 0x02 0x00 0x0f B 0x17 0x01 0x19 0x16 
after round trip, plain string is 'This is pla' 

выход из линии я отмеченную выше (то есть, сохраняя значение n в качестве исходной длины строки), ваш результат

encrypted string: 
0x15 0x0a 0x0a 0x17 A 0x0b 0x10 D 0x11 0x0e 0x02 0x00 0x0f B 0x17 0x01 0x19 0x16 
after round trip, plain string is 'This is plain text' 

как и следовало ожидать.

+1

Интересно отметить в «зашифрованном» тексте: было несколько «печатных» символов, в частности A (5th), D (8-й), B (14-й). Они соответствуют SPACES в исходном тексте, и результатом является буква UPPERCASE строки ключа. Это не совпадение и настоящая слабость этого метода. Особенно, если ключ короткий, вы можете быстро собрать все это вместе ... должно быть строго для развлечения, а не для фактического шифрования. – Floris

Смежные вопросы