c - 文件解密时出现 "EVP_DecryptFInal_ex: bad decrypt"如何解析

标签 c encryption openssl

我有以下问题。有人可以给我建议一个解决方案吗。

我是第一次做文件的加密和解密。

我使用以下命令通过命令提示符加密了文件:

openssl enc -aes-256-cbc -in file.txt -out file.enc -k "key value" -iv "iv value"

我必须以编程方式解密它。所以我已经为它编写了程序,但它抛出了以下错误:

./exe_file enc_file_directory
...
error: 06065064: digital envelope routines: EVP_DecryptFInal_ex: bad decrypt: evp_enc.c

下面的程序将输入作为目录路径并搜索加密文件“.enc”并尝试将其读入缓冲区进行解密。

代码:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <dirent.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <openssl/evp.h>
#include <openssl/err.h>
#include <openssl/conf.h>
#include <libxml/globals.h>

void handleErrors(char *msg)
{
    {
        ERR_print_errors_fp(stderr);
        printf("%s", msg);
        abort(); 
    }
}

void freeMemory(char *mem)
{
    if (NULL != mem)
    {
        free(mem);
        mem = NULL;
    }
}

/* Function to decrypt the XML files */

int decryptXML(unsigned char *indata, unsigned char *outdata, int fsize)
{

    int outlen1 = 0, outlen2 = 0;

    unsigned char iv[] = "b63e541bc9ece19a1339df4f8720dcc3";
    unsigned char ckey[] = "70bbc518c57acca2c2001694648c40ddaf19e3b4fe1376ad656de8887a0a5ec2" ;

    if (NULL == indata)
    {
        printf ("input data is empty\n");
        return 0;
    }

    if (0 >= fsize)
    {
        printf ("file size is zero\n");
        return 0;
    }

    outdata = (char *) malloc (sizeof (char) * fsize * 2);

    EVP_CIPHER_CTX ctx;

    EVP_CIPHER_CTX_init(&ctx);

    if (! EVP_DecryptInit_ex (&ctx, EVP_aes_256_cbc(), NULL, ckey, iv))
    {
        EVP_CIPHER_CTX_cleanup(&ctx);
    handleErrors("DInit");
    }

    if (! EVP_DecryptUpdate (&ctx, outdata, &outlen1, indata, fsize))
    {
        EVP_CIPHER_CTX_cleanup(&ctx);
        handleErrors("DUpdate");
    }

    if (! EVP_DecryptFinal_ex (&ctx, outdata + outlen1, &outlen2))
    {

        EVP_CIPHER_CTX_cleanup(&ctx);
        handleErrors("DFinal");
    }

    EVP_CIPHER_CTX_cleanup(&ctx);

    return outlen1+outlen2;

}

int isDirectory(char *path)
{
    DIR *dir = NULL;
    FILE *fin = NULL, *fout = NULL;
    int enc_len = 0, dec_len = 0, fsize = 0, ksize = 0;
    unsigned char *indata = NULL, *outdata = NULL;
    char buff[BUFFER_SIZE], file_path[BUFFER_SIZE], cur_dir[BUFFER_SIZE];

    struct dirent *in_dir;
    struct stat s;

    if (NULL == (dir = opendir(path)))
    {
        printf ("ERROR: Failed to open the directory %s\n", path);
        perror("cannot open.");
        exit(1);
    }

    while (NULL != (in_dir = readdir(dir)))
    {

        if (!strcmp (in_dir->d_name, ".") || !strcmp(in_dir->d_name, ".."))
            continue;

        sprintf (buff, "%s/%s", path, in_dir->d_name);

        if (-1 == stat(buff, &s))
        {
            perror("stat");
            exit(1);
        }

        if (S_ISDIR(s.st_mode))
        {

            isDirectory(buff);
        }
        else
        {
            strcpy(file_path, buff);

            if (strstr(file_path, ".enc"))
            {

                /* File to be decrypted */

                fout = fopen(file_path,"rb"); 

                fseek (fout, 0L, SEEK_END);
                fsize = ftell(fout);
                fseek (fout, 0L, SEEK_SET);

                indata = (char*)malloc(fsize);

                fread (indata, sizeof(char), fsize, fout);

                if (NULL == fout)
                {
                    perror("Cannot open enc file: ");
                    return 1;
                }


                dec_len = decryptXML (indata, outdata, fsize);
                outdata[dec_len] = '\0';
                printf ("%s\n", outdata);
                fclose (fin);
                fclose (fout);

            }
        }
    }



    closedir(dir);
    freeMemory(outdata);
    freeMemory(indata);

    return 1; 
}


int main(int argc, char *argv[])
{
    int result;

    if (argc != 2)
    {
        printf ("Usage: <executable> path_of_the_files\n");
        return -1;
    }

    ERR_load_crypto_strings();
    OpenSSL_add_all_algorithms();
    OPENSSL_config(NULL);

    /* Checking for the directory existance */

    result = isDirectory(argv[1]);

    EVP_cleanup();
    ERR_free_strings();

    if (0 == result)
        return 1;
    else
       return 0;
}

谢谢。

最佳答案

当您使用不兼容版本的 openssl 进行加密和解密时,也会出现此消息 digital envelope routines: EVP_DecryptFInal_ex: bad decrypt

我遇到的问题是我在具有 1.1.0 版本的 Windows 上加密,然后在具有 1.0.2g 的通用 Linux 系统上解密。

这不是一个非常有用的错误信息!


工作解决方案:

来自@AndrewSavinykh 的可能解决方案适用于许多人(参见评论):

Default digest has changed between those versions from md5 to sha256. One can specify the default digest on the command line as -md sha256 or -md md5 respectively

关于c - 文件解密时出现 "EVP_DecryptFInal_ex: bad decrypt"如何解析,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34304570/

相关文章:

c - 在 C 中,释放一半的内存块,而不释放另一半

javascript - 如何避免在 http header 中显示表单数据

java - Java 实现中的 BouncyCaSTLe PGP 文本模式不会转换为 CR/LF

sql-server - OpenSSL:获取 SQL Server 公共(public)证书

haskell - cabal-在 Windows 上安装 Hopenssl

c - 如果(fork())fork()

c - 在 C 中扩展结构

encryption - 能够分解大量数字如何决定流行加密算法的安全性?

c# - 如何在 C# 中实现 BN_num_bytes() (和 BN_num_bits() )?

c - 如何将 char* 复制到 const char*?