使用openssl解密文件

时间:2015-07-16 16:20:25

标签: c linux openssl cryptography aes

我试图解密我最初使用openssl加密的文件:

#include <stdio.h>
#include <openssl/aes.h>
#include <string.h>
#include <stdlib.h>

const static unsigned char aes_key[]={"passwordpasswor"}; //15 characters + \0

int main(int argc, char *argv[]) {
if (argc>1) {
  if (strcmp("encrypt",argv[1])==0) {
    FILE *file;
    file=fopen("file.txt","w+b");
    unsigned char aes_input[]="#!/bin/bash\necho hello world\0";
    unsigned char iv[AES_BLOCK_SIZE];
    memset (iv,0x00,AES_BLOCK_SIZE);
    unsigned char enc_out[sizeof(aes_input)];
    unsigned char dec_out[sizeof(aes_input)];
    AES_KEY enc_key,dec_key;
    AES_set_encrypt_key(aes_key,sizeof(aes_key)*8,&enc_key);
    AES_cbc_encrypt(aes_input,enc_out,sizeof(aes_input),&enc_key,iv,AES_ENCRYPT);
    //decryption
    memset(iv,0x00,AES_BLOCK_SIZE);
    AES_set_decrypt_key(aes_key,sizeof(aes_key)*8,&dec_key);
    AES_cbc_encrypt(enc_out,dec_out,sizeof(aes_input),&dec_key,iv,AES_DECRYPT);
    //verify
    printf("original %s\n",aes_input);
    hex_print(enc_out, sizeof enc_out);
    printf("sizeof enc_out is %i\n",sizeof(enc_out));
    fwrite(enc_out,1,sizeof(enc_out),file);
    printf("decrypted %s\n",dec_out);
    }

  if (strcmp("decrypt",argv[1])==0) {
    printf("decrypt\n");
    FILE *file;
    char * ciphertext=0;
    int file_length;
    file=fopen("file.txt","r+b");
    if (file) {
      fseek (file,0,SEEK_END);
      file_length= ftell(file);
      fseek(file,0,SEEK_SET);
      ciphertext=malloc(file_length);
      if (ciphertext)
        fread(ciphertext,1,file_length,file);
      fclose(file);
      }
    //printf("ciphertext is %s\n",ciphertext);

    //begin decryption
    AES_KEY dec_key;
    unsigned char enc_out[sizeof(ciphertext)];
    unsigned char iv[AES_BLOCK_SIZE];
    memset (iv,0x00,AES_BLOCK_SIZE);
    AES_set_decrypt_key(aes_key,sizeof(aes_key)*8,&dec_key);
    AES_cbc_encrypt(ciphertext,enc_out,sizeof(ciphertext),&dec_key,iv,AES_DECRYPT);
    printf("original string is %s\n",enc_out);
    }

  }
    return 0;
}

我也在加密函数中测试解密(在写入或读取文件之前直接解密)工作正常 然而,独立解密功能没有正确解密:

decrypt
original string is #!/bin/b�:�j�

由于解密工作正常,我假设它正在写入文件或从文件读取到导致这种乱码输出的字符串。

我做错了什么?

感谢。

1 个答案:

答案 0 :(得分:1)

我有一些建议可能会有所帮助。最重要的是缓冲管理。

  1. 在第一部分中关闭加密文件。此外,您不需要null终止在引号中声明的字符串。例如,"hello world"不是"hello world\0"这将等同于您的cstring中的"hello world\0\0"(它将被视为"hello world\0")。这更像是一种惯例。

  2. 制定条件ifelse if,否则您将始终执行这两项检查。

  3. 我的理解是openssl的加密/解密函数处理缓冲区并使用sizeof(缓冲区)是不可靠的。我相信这些函数会返回输出的长度,因此您应该将其保存在变量中并使用它。

  4. 密钥带走,使用具有正确缓冲区大小的fwrite函数,而不使用sizeof。由于加密会为您提供伪随机字符,因此您可能在结束之前在缓冲区中使用空终止符。

    以下是使用AES256 CBC的openssl手册的链接。我最近用它来加密和解密文件,它对我有用。我会提供一个代码片段,但它有点长。不幸的是,它使用的功能与您当前使用的功能不同。 https://wiki.openssl.org/index.php/EVP_Symmetric_Encryption_and_Decryption