-1

暗号化:

while(!feof(fp)){
    memset(plain_text, 0, sizeof(plain_text));
    retval = fread(plain_text, 1, 16, fp);
    if(!retval) break;
    for(i=0; i<16; i++){
        if(plain_text[i] == 0){
            for(j=i; j<16; j++){
                plain_text[j] = 0x0i;
            }
            break;
        }
    }
    gcry_cipher_encrypt(hd, encBuffer, txtLenght, plain_text, txtLenght);
    fwrite(encBuffer, 1, 16, fpout);
}

復号化:

while(!feof(fp)){
    memset(plain_text, 0, sizeof(plain_text));
    retval = fread(plain_text, 1, 16, fp);
    if(!retval) break;
    gcry_cipher_decrypt(hd, encBuffer, txtLenght, plain_text, txtLenght);
    for(i=0; i<16; i++){
        if(encBuffer[i] == 0x0i){
            j = 0;
            j += i;
            if(encBuffer[++i] == 0x0j){
                last = 1;
                i--;
                j=i;
                printf("found a %d\n", i);
                break;
            }
            else i--;
        }
    }
    //printf("%d\n", j);
    if(last == 1) fwrite(encBuffer, 1, j, fpout);
    else fwrite(encBuffer, 1, 16, fpout);
}

pkcs#7 標準から取り外し可能なパディングを追加しようとしていますが、問題があります。
txt ファイルを扱う場合、プログラムは完全に動作しますが、 tar.gz または pdf ファイルを復号化しようとすると、復号化プログラムはファイル サイズの半分で停止します。
たとえば、サイズが 28272 バイトの tar.gz アーカイブを見てみましょう (prova は元のファイル、out は暗号化されたファイル、origdec は復号化されたファイルです)。

28272   prova
28272   out
12147   origdec

gnu/linux で libgcrypt を使用しています。

4

2 に答える 2

3

多くのことが間違っています:

  • ゼロバイトを含むブロックにパディングを追加しています。tar.gz などのバイナリ ファイルには、テキスト ファイルとは異なり、多くのゼロ バイトが含まれている可能性があります。fread の戻り値 (< 16) を見て、読み取りエラーが発生した場合に ferror をチェックすることで、最後のブロック (およびそのサイズ) をいつ読み取ったかを特定する必要があります。
  • i と j だけを意味する場合は、0xi と 0xj を使用しています。
  • PKCS#7 の場合、残りのデータ バイトである i ではなく、パディング値 (16-i) としてパディング バイト数を書き込む必要があります。
  • 復号化では、任意のブロックで何らかの方法でパディングを検出しようとしています。これが、decryot が短い理由です。すべての暗号文を読み取って解読し、最後のブロックからのみパディングを削除する必要があります。

それが役立つことを願っています!

于 2013-01-08T19:10:24.270 に答える
3

問題はおそらく、知らないうちに GCC の C 言語の拡張機能である虚数を使用していることです。リテラル0x0i0x0jは虚数リテラルです。変数に他の名前を使用すると、コンパイル エラーが発生します。

数字の表現と数字の表現を間違えているようです。プログラムでは、整数リテラル0x0aはバイナリ表現 00001010 の表現です。これは、変数を 16 進数として表現する代わりに、直接使用できることを意味しiますj

plain_text[j] = i;

if(encBuffer[i] == i)
于 2013-01-07T14:07:59.817 に答える