c aes256用pkcs#7标准填充

时间:2013-01-07 13:29:42

标签: c aes libgcrypt

加密:

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!

2 个答案:

答案 0 :(得分:3)

问题可能是,在您不知情的情况下,您在GCC中使用C语言的扩展:虚数。文字0x0i0x0j是虚数字文字。如果对变量使用任何其他名称,则会出现编译错误。

似乎你错误地将数字的表示与它们的表示相混淆。在您的程序中,整数文字0x0a是二进制表示00001010的表示。这意味着您可以直接使用变量ij,而不是尝试将它们呈现为十六进制数:

plain_text[j] = i;

if(encBuffer[i] == i)

答案 1 :(得分:3)

有很多错误:

  • 您正在将填充添加到包含零字节的任何块。与文本文件不同,诸如tar.gz之类的二进制文件可能包含许多零字节。您需要通过查看fread的返回值(它将是&lt; 16)来识别何时读取最后一个块(及其大小),并在发生读取错误时检查ferror。
  • 当你的意思是i和j时,你正在使用0xi和0xj。
  • 对于PKCS#7,您需要将填充字节数写为填充值(16-i),而不是i,这是剩余的数据字节。
  • 在解密时,您试图在任何块中以某种方式检测填充。这就是你的解密很短的原因。您需要读取和解密所有密文,然后仅从最后一个块中删除填充。

希望有所帮助!