【问题标题】:c aes256 padding with pkcs#7 standardc aes256 使用 pkcs#7 标准填充
【发布时间】:2013-01-07 13:29:42
【问题描述】:

加密:

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!

【问题讨论】:

  • while这个条件是不是有点傻?
  • 什么是0x0i 和0x0j?那甚至不应该编译。
  • @JoachimPileborg 他们是两个int!我用它们作为索引在数组中搜索
  • @KerrekSB 可能:D 我正在尝试使程序正常工作,之后我将清理我的代码 xD

标签: c aes libgcrypt


【解决方案1】:

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

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

plain_text[j] = i;

和

if(encBuffer[i] == i)

【讨论】:

    【解决方案2】:

    错的地方很多:

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

    希望有帮助!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-01-27
      • 2013-11-14
      • 2011-03-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多