web-dev-qa-db-ja.com

単純な復号化方法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
}

したがって、基本的には文字列を暗号化した後、同じ暗号化キーを使用して以前に暗号化された文字列を復号化します。

私はプログラミングにかなり慣れていないので、以前に暗号化された文字列を解読する方法を知りたいだけです。おかげで、すべての助けに感謝します。

9
user3101398

XOR暗号化の優れた点の1つは、暗号化を2回適用すると、元の文字列が返されることです– http://en.wikipedia.org/wiki/XOR_cipherを参照)

関数xor_decryptでは、文字列とキーを受け取り、文字列^キーを返します。ここで、もう一度キーでxorを実行すると、(string ^ key)^ key = string ^(key ^ key)= string ^ identity = string(XOR operatorのプロパティによる)が得られます: http://en.wikipedia.org/wiki/Exclusive_or#Properties

したがって、最初のxor_encryptの出力で2回目に関数xor_encryptを実行できます。

13
dmitrig01

XORでは、復号化は暗号化とまったく同じ操作です。暗号化された文字列をxor_encryptメソッドでもう一度同じキーで実行すると、プレーンテキストが返されます。

警告1:null文字

注意すべきことの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 ==文字列の問題を認識しない)結果、復号化が切り捨てられます(iplainkeyの同じ文字と一致します):

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'

あなたが期待するとおり正確に。

11
Floris