首页 > 解决方案 > 通过Openssl命令行加密,通过c++解密

问题描述

我正在尝试通过 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 使用的版本不同吗?或者是否有一些通过命令行设置的其他选项我没有包含在我的解密功能中?

标签: c++encryptionopensslcryptographyaes

解决方案


我现在发现了2个问题:

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

推荐阅读