インターネットで次の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
}
したがって、基本的には文字列を暗号化した後、同じ暗号化キーを使用して以前に暗号化された文字列を復号化します。
私はプログラミングにかなり慣れていないので、以前に暗号化された文字列を解読する方法を知りたいだけです。おかげで、すべての助けに感謝します。
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を実行できます。
XORでは、復号化は暗号化とまったく同じ操作です。暗号化された文字列をxor_encrypt
メソッドでもう一度同じキーで実行すると、プレーンテキストが返されます。
注意すべきことの1つは、文字列内の文字がキー内の対応する文字と一致する場合、結果は'\0'
になります。これは、現在のコードによって「文字列の終わり」として解釈され、解読不足を防ぎます。これを回避するには、「実際の」文字列の長さを関数のパラメーターとして渡します。
また、キーの最後を超えて実行しないようにしてください。プレーンテキストが非常に長い場合は、キーを繰り返す必要がある場合があります。これは、%
演算子で実行できます。最初からキーをリサイクルするだけです。
これらの手法を示す完全な例を次に示します。
#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 ==文字列の問題を認識しない)結果、復号化が切り捨てられます(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'
あなたが期待するとおり正確に。