通过Openssl命令行加密并通过c ++解密

时间:2018-10-25 16:08:12

标签: c++ encryption openssl cryptography aes

我正在尝试通过openssl命令行加密文件,并通过c ++对其解密。我正在运行命令:

openssl enc -aes-256-cbc -e -in test.txt -out test.txt.enc -K (64 character length key) -iv (32 character length iv)

这是我用于解密的c ++代码:

typedef struct cipher_params_t {
unsigned char *key;
unsigned char *iv;
unsigned int encrypt;
const EVP_CIPHER *cipher_type;
}

 void file_decrypt(cipher_params_t *params, FILE *ifp, FILE *ofp){

    int cipher_block_size = EVP_CIPHER_block_size(params->cipher_type);
    unsigned char in_buf[BUFSIZE], out_buf[BUFSIZE + cipher_block_size];

    int num_bytes_read, out_len;
    EVP_CIPHER_CTX *ctx;

    ctx = EVP_CIPHER_CTX_new();
    if(ctx == NULL){
        fprintf(stderr, "ERROR: EVP_CIPHER_CTX_new failed. OpenSSL error: %s\n", ERR_error_string(ERR_get_error(), NULL));
        cleanup(params, ifp, ofp, ERR_EVP_CTX_NEW);
    }



    if(!EVP_DecryptInit_ex(ctx, params-> cipher_type, NULL, params->key, params->iv)){
        fprintf(stderr, "ERROR: EVP_CipherInit_ex failed. OpenSSL error: %s\n", ERR_error_string(ERR_get_error(), NULL));
        EVP_CIPHER_CTX_cleanup(ctx);
        cleanup(params, ifp, ofp, ERR_EVP_CIPHER_INIT);
    }

    while(1){

        num_bytes_read = fread(in_buf, sizeof(unsigned char), BUFSIZE, ifp);
        if (ferror(ifp)){
            fprintf(stderr, "ERROR: fread error: %s\n", strerror(errno));
            EVP_CIPHER_CTX_cleanup(ctx);
            cleanup(params, ifp, ofp, errno);
        }
        if(!EVP_DecryptUpdate(ctx, out_buf, &out_len, in_buf, num_bytes_read)){
            fprintf(stderr, "ERROR: EVP_CipherUpdate failed. OpenSSL error: %s\n", ERR_error_string(ERR_get_error(), NULL));
            EVP_CIPHER_CTX_cleanup(ctx);
            cleanup(params, ifp, ofp, ERR_EVP_CIPHER_UPDATE);
        }
        fwrite(out_buf, sizeof(unsigned char), out_len, ofp);
        if (ferror(ofp)) {
            fprintf(stderr, "ERROR: fwrite error: %s\n", strerror(errno));
            EVP_CIPHER_CTX_cleanup(ctx);
            cleanup(params, ifp, ofp, errno);
        }
        if (num_bytes_read < BUFSIZE) {
            /* Reached End of file */
            break;
        }
    }

    /* Now cipher the final block and write it out to file */
    if(!EVP_DecryptFinal_ex(ctx, out_buf, &out_len)){
        fprintf(stderr, "ERROR: EVP_CipherFinal_ex failed. OpenSSL error: %s\n", ERR_error_string(ERR_get_error(), NULL));
        EVP_CIPHER_CTX_cleanup(ctx);
        cleanup(params, ifp, ofp, ERR_EVP_CIPHER_FINAL);
    }
    fwrite(out_buf, sizeof(unsigned char), out_len, ofp);
    if (ferror(ofp)) {
        fprintf(stderr, "ERROR: fwrite error: %s\n", strerror(errno));
        EVP_CIPHER_CTX_cleanup(ctx);
        cleanup(params, ifp, ofp, errno);
    }
    EVP_CIPHER_CTX_cleanup(ctx);
}



int main()
{
FILE *f_input, *f_dec;

cipher_params_t *params = (cipher_params_t *) malloc(sizeof(cipher_params_t));
unsigned char key[] = "(my 64 character length key"
unsigned char iv[] = "(my 64 character length IV)"


f_input = fopen("encrypted_file", "rb");
if (!f_input) {
    /* Unable to open file for reading */
    fprintf(stderr, "ERROR: fopen error: %s\n", strerror(errno));
    return errno;
}

f_dec = fopen("decrypted_file", "wb");
if (!f_dec) {
    /* Unable to open file for writing */
    fprintf(stderr, "ERROR: fopen error: %s\n", strerror(errno));
    return errno;
}

file_decrypt(params, f_input, f_dec);


fclose(f_input);
fclose(f_dec);


free(params);

return 0;
}

我收到错误消息:ERROR: EVP_CipherFinal_ex failed. OpenSSL error: error:06065064:lib(6):func(101):reason(100)

当我将解密功能转换为加密以加密文件,然后将所有内容切换回该文件以进行解密时,我能够成功解密该文件,但不能通过命令行完成解密。如果有帮助,我正在使用OpenSSL 1.0.1e-fips版本

我正在使用加密库在Eclipse上运行它。

这可能是由于命令行版本与使用的eclipse版本不同吗?还是在命令行中设置了我未包含在解密函数中的其他选项?

1 个答案:

答案 0 :(得分:0)

我现在发现了2个问题:

  1. 您尚未在主体中将keyiv分配给params结构。
  2. 请记住,在代码keyiv中应分别使用32字节和16字节的密钥,而不是发送到命令行的十六进制字符串。将命令行转换为实数字节数组keyiv