1

これは、一部の人にとっては非常に簡単かもしれません。XOR 暗号化ファイルがクリトアナリシスとブルート フォースを使用してどのように解読されるのか、よくわかりません。8 バイト x 8 バイトを XOR するプログラムを使用して暗号化された PDF ファイルがあります。プログラムのコードは

int main(int argc, char** argv) {

if (argc!=3) {
  printf("command (for example) : ./enc1 file_to_encrypt key_in_hex\n");
  return 1;
}

// get the key
unsigned long long key=strtoull(argv[2], NULL, 16);

// open the file
char* file=argv[1];
int fdp=open(file, O_RDONLY);
if (fdp<0) {
   printf("cannot open the file %s\n", file);
   return 1;
} 

 // open the file to save the encryption
 char enc[strlen(file)+10];
 strncpy(enc, file, strlen(file));
 strncpy(enc+strlen(file), ".enc1\0", 5);
 enc[strlen(file)+5]='\0';
 int fdc=open(enc, O_CREAT|O_WRONLY, S_IRUSR|S_IWUSR);

 if (fdc<0) {
    printf("cannot save the encrypted file %s\n", enc);
    return 1;
}

  // encryption
  unsigned long long buf;
  unsigned long long k;
  int len;
  k=key;
  while ((len=read(fdp, (char*)&buf, 8))>0) {
  buf^=k;
  k*=key;
   write(fdc, (char*)&buf, len);
 }

 close(fdp);
 close(fdc);
 return 0;
}

PDFファイルのヘッダーが

%PDF-1.0 %PDF-1.1

その情報を使用して平文を取得するにはどうすればよいですか? ヘッダーを Xored しますか? どうもありがとう

4

3 に答える 3

1

XOR は簡単に元に戻すことができます。m が元のファイルで、e がその暗号化されたバージョンであるとします。それで

e[0] = k[0] ^ m[0]
e[1] = k[1] ^ m[1]
e[2] = k[2] ^ m[2]
e[3] = k[3] ^ m[3]

ただし、XOR は可逆なので、e と m の一部を知ることで k を見つけることができます。

k[0] = e[0] ^ m[0]
k[1] = e[1] ^ m[1]
k[2] = e[2] ^ m[2]
k[3] = e[3] ^ m[3]
于 2012-04-23T17:39:04.880 に答える
1

OPは回答を受け入れておらず、まだ質問があるようです.user1202136とOmnipotentEntityによる私の回答を次に示します。

キーを決定するには、暗号化されたファイルの最初の 8 文字と、予想されるヘッダー文字列 (%PDF-1.4 など) を文字ごとに XOR します。結果は同じ長さの文字列で、キーの にコピーできますunsigned long long(これも 8 バイトを占めます)。strtoullには 16 の基本パラメーターが与えられているため、プログラムは 16 進数のキー値を想定しています。したがって、%llx指定子を使用して結果をフォーマットします。そうしないと、10 進数になり、機能しません。

void find_key(const char *filename, const char *m)
{
    // open the encrypted file
    FILE *fp = fopen(filename, "r");
    if (!fp)
        return;

    // read encrypted header
    char e[8];
    for (int i = 0; i < 8; i++)
        e[i] = fgetc(fp);
    fclose(fp);

    // xor with known header
    char k[8];
    for (int j = 0; j < 8; j++)
        k[j] = e[j] ^ m[j];

    // copy into 8 byte value, and output in base-16
    unsigned long long newkey;
    memcpy(&newkey, &k, 8);
    printf("Testing for %s gives key %llx\n", m, newkey);
}

ヘッダーのバージョンがわからないので、さまざまなオプションで数回実行してください。暗号化されたファイルがこれらの .pdf バージョンのいずれかである場合、それを復号化するためのキーが得られます。

int main(int argc, char *argv[])
{
    if (argc != 2)
        return 1;
    find_key(argv[1], "%PDF-1.0");
    find_key(argv[1], "%PDF-1.1");
    find_key(argv[1], "%PDF-1.2");
    find_key(argv[1], "%PDF-1.3");
    find_key(argv[1], "%PDF-1.4");
    return 0;
}

プログラムは、暗号化と復号化の両方に使用されます。これは、上記で回答した XOR の可逆的な性質によるものです。暗号化されたファイル名と生成されたキーをパラメーターとして渡します。

このテスト例では、最初にプログラムを使用して特定のキーで .pdf を暗号化し、次に上記の方法でキーを再度見つけてから、最良のキー結果を使用してプログラムで復号化します。

$ ./enc1 test.pdf 1234ABCD
$ ./find-key test.pdf.enc1 
Testing for %PDF-1.0 gives key 30000001234abcd
Testing for %PDF-1.1 gives key 20000001234abcd
Testing for %PDF-1.2 gives key 10000001234abcd
Testing for %PDF-1.3 gives key 1234abcd
Testing for %PDF-1.4 gives key 70000001234abcd
$ ./enc1 test.pdf.enc1 1234abcd

お役に立てれば。

于 2012-04-26T18:57:40.723 に答える
0

user1202136の回答に追加するには、

n同じキーでエンコードされた 2 つの異なるメッセージがある場合、キーの最初の文字 (および両方のメッセージ) を取得できます(nは短い方のメッセージの長さです) (これが WEP クラッキングの仕組みです)。コードではなく、数学です。)

eA[0] = k[0] ^ mA[0]
eB[0] = k[0] ^ mB[0]
eA[0] ^ eB[0] = k[0] ^ k[0] ^ mA[0] ^ mB[0]
eA[0] ^ eB[0] = mA[0] ^ mB[0]
eA[0] ^ eB[0] ^ mA[0] = mB[0]
mB[0] ^ eB[0] = k[0]
于 2012-04-23T17:43:35.590 に答える