首页 文章

在编写文件时如何“手动”表示EOF?

提问于
浏览
-1

我有这个功能:

int cipher_file(char *file_path, uint8_t *key, int key_size){

    FILE *file;
    size_t read_char_count, wrote_char_count;

    fpos_t *pos = malloc(sizeof(fpos_t));
    char *block = malloc(16*sizeof(uint8_t));

    if ( !(file = fopen(file_path, "rb+")) ) {
      return EXIT_FAILURE;
    }

    while(!feof(file)){

      while( ( read_char_count = fread(block, 1, 16*sizeof(uint8_t), file) ) > 0 ) {
        block = cipher_block(block, key, key_size);
        fseek(file, -read_char_count, SEEK_CUR);
        wrote_char_count = fwrite(block , 1, 16*sizeof(uint8_t), file);
      }

    }
    fclose(file);
    return EXIT_SUCCESS;
}

(我知道ECB模式不安全btw)

它接收一个文件,将其分解为128位的块,使用AES对它们进行加密并将它们写回文件,从而有效地用密文替换纯文本 . 我还写了一个函数 decipher_file() 来解密文件 .

问题是如果文件大小不是128位的倍数,最后fread()只用部分成功读取的字符部分替换“block”(16字节长)的内容,留下一堆垃圾 . 先前的加密块 .

解密时,因为decipher_file()通常无法知道原始文件的大小,所以它会解密所有内容,包括垃圾字符,并将其写回文件 .

我也尝试在每一轮用零填充“块”初始化,但是,毫不奇怪,它们也被添加到文件中,这可能是非常有问题的 .

所以我的问题是,是否有一种方式(如函数)表示文件结束的位置,或告诉fwrite()停止写入?

1 回答

  • 1

    您不能使用特殊字符,因为加密数据最终可能看起来像它 . 无论如何,这不是一个优雅的解决方案 .

    有多种解决方案:

    • 使用解密的内容长度作为前缀 . 这非常干净,易于实施 .

    • 使用保留长度信息的密码模式 . 欧洲央行没有 . 使用填充方案或方案,保留长度,如计数器模式 .

相关问题