crypto_secretbox_easy 在文本末尾附加几个“[NUL]”字符

问题描述 投票:0回答:1

我创建了两个函数“encryptf”和“decrytpf”(用“f”命名以避免与预先存在的 libsodium 函数发生命名冲突。这些函数非常不言自明,它们使用提供的提供的加密和解密给定的输入字符串关键。

以下是加密方法。应该注意的是,“密钥”是一个简单的随机生成的 ANSI 字符字符串。

int encryptf(const char *input_file, const char *output_file, const unsigned char *key) {  
    if (sodium_init() < 0) {  
        printf("Error initializing\n");  
        return 1;  
    }  
  
    // Get input and output files and ensure read/write, creation if needed.  
  FILE *input = fopen(input_file, "r");  
    FILE *output = fopen(output_file, "ab+");  
    if (!input || !output) {  
        printf("Error opening files to encrypt\n");  
        return 1;  
    }  
  
    // Get file size  
  fseek(input, 0, SEEK_END);  
    size_t file_size = ftell(input);  
    fseek(input, 0, SEEK_SET);  
  
    // Allocate memory for plaintext and ciphertext  
  unsigned char *plaintext = (unsigned char *) malloc(file_size);  
    unsigned char *ciphertext = (unsigned char *) malloc(file_size + crypto_secretbox_MACBYTES);  
  
    // Create nonce char array, and populate it with secure randombytes from libsodium library  
  unsigned char nonce[crypto_secretbox_NONCEBYTES];  
    randombytes(nonce, sizeof(nonce));  
  
    // Read plaintext from file  
  fread(plaintext, 1, file_size, input);  
  
    // Create 'mac' array to get rid of authentication tag.  
  unsigned char mac[crypto_secretbox_NONCEBYTES];  
  
    // Encrypt plaintext  
  crypto_secretbox_easy(ciphertext, plaintext, file_size, nonce, key);  
  
    // Write nonce and ciphertext to output file  
  fwrite(nonce, 1, sizeof(nonce), output);  
    fwrite(ciphertext, 1, file_size + crypto_secretbox_MACBYTES, output);  
  
    // Cleanup  
  fclose(input);  
    fclose(output);  
    free(plaintext);  
    free(ciphertext);  
  
    return 0;  
}

以及解密功能:

int decryptf(const char *input_file, const char *output_file, const unsigned char *key) {  
    if (sodium_init() < 0) {  
        printf("Error initializing Libsodium\n");  
        return 1;  
    }  
  
    FILE *input = fopen(input_file, "rb");  
    FILE *output = fopen(output_file, "wb");  
    if (!input || !output) {  
        printf("Error opening files to decrypt\n");  
        return 1;  
    }  
  
    // Read nonce from file  
  unsigned char nonce[crypto_secretbox_NONCEBYTES];  
    fread(nonce, 1, sizeof(nonce), input);  
  
    // Get file size excluding nonce  
  fseek(input, 0, SEEK_END);  
    size_t file_size = ftell(input) - crypto_secretbox_NONCEBYTES;  
    fseek(input, crypto_secretbox_NONCEBYTES, SEEK_SET);  
  
    // Allocate memory for ciphertext and plaintext  
  unsigned char *ciphertext = (unsigned char *) malloc(file_size);  
    unsigned char *plaintext = (unsigned char *) malloc(file_size);  
  
    // Read ciphertext from file  
  fread(ciphertext, 1, file_size, input);  
  
    // Decrypt ciphertext  
  if (crypto_secretbox_open_easy(plaintext, ciphertext, file_size, nonce, key) != 0) {  
        printf("Error decrypting %s\n", input_file);  
        return 1;  
    }  
  
    // Write plaintext to output file  
  fwrite(plaintext, 1, file_size, output);  
  
    // Cleanup  
  fclose(input);  
    fclose(output);  
    free(ciphertext);  
    free(plaintext);  
  
    return 0;  
}

以下是我如何运行这些函数的基本示例。这不是我的确切代码,但充分说明了我如何使用这些函数而不暴露我的代码库:

int main(void) {
    FILE *f1 = fopen("tests/file.txt", "ab+");  
  
    if (!f1 || !f2) {  
        printf("Failed create test files.\n");  
        exit(EXIT_SUCCESS);  
    }  
    fprintf(f1, "HELLO\n\nworld!\n..\n\thello\n../14hf\n1");  
    fclose(f1); 

    char *key = rand_string(32);
    encryptf("tests/file.txt", "tests/file_enc.txt", key);
        printf("File encrypted.\n");

        decryptf("tests/file_enc.txt", "tests/file.txt", fkey);
}

这确实会解密文件的内容,但还会在末尾附加以下奇怪的字符:

Strange characters

(我知道堆栈溢出不喜欢图像,但似乎我的键盘无法复制它们,或者无法显示它们,因为复制/粘贴它们没有任何作用。)

我确信删除这些字符很重要,因为我不想在加密/解密之前或之后留下任何痕迹或解密方式,或在没有密钥的情况下获取有关这些文件的任何信息。

我尝试删除 libsodium 提供的身份验证代码,因为我希望这可能是问题所在,但这样做似乎会破坏文件解密过程。

我不确定这是否重要,但我正在使用苹果 M2 芯片的 2023 款 MacBook Pro 上运行。

感谢大家提供的任何帮助!

c macos cryptography libsodium
1个回答
0
投票

对于所有可能遇到同样问题的人,我通过改变我使用的方式解决了它

fwrite
,来自:

fwrite(plaintext, 1, file_size, output);

fwrite(plaintext, 1, file_size - crypto_secretbox_MACBYTES, output);

考虑

crypto_secretbox_easy
添加的 MAC 身份验证标签。

© www.soinside.com 2019 - 2024. All rights reserved.