如何在文件解密期间解决"EVP_DecryptFInal_ex:bad decrypt"

Sai*_*Sai 45 c encryption openssl

我有以下查询.可以任何人请建议我一个解决方案.

我是第一次加密和解密文件.

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

openssl enc -aes-256-cbc -in file.txt -out file.enc -k "key value" -iv "iv value"
Run Code Online (Sandbox Code Playgroud)

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

./exe_file enc_file_directory
...
error: 06065064: digital envelope routines: EVP_DecryptFInal_ex: bad decrypt: evp_enc.c
Run Code Online (Sandbox Code Playgroud)

下面的程序将输入作为目录路径并搜索加密文件".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;
}
Run Code Online (Sandbox Code Playgroud)

谢谢.

Sea*_*son 98

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

我遇到的问题是我在Windows上进行了加密,版本为1.1.0,然后在一个1.0.2g的通用Linux系统上进行解密.

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

  • 请参阅此处:/sf/answers/2774896491/默认摘要在从md5到sha256的版本之间已更改.可以将命令行上的默认摘要分别指定为`-md sha256`或`-md md5` (66认同)
  • 我刚刚从 Kubuntu artful 升级到 Kubuntu bionic,它将 openssl 从 1.0.2g 更新到 1.1.0g,但我无法解密一些文件。`openssl enc` 用于基于密码的密钥派生的默认哈希在 1.1.0 中更改为 SHA256,而在较低版本中更改为 MD5 ([source](https://unix.stackexchange.com/a/344586))。我的解决方案是[下载旧的`openssl`包](https://packages.ubuntu.com/artful/openssl),用`dpkg`强制安装它,解密文件,强制更新`openssl`从存储库中打包(例如使用 Synaptic)并再次加密文件。 (2认同)
  • 谢谢您的回答!不管怎样,必须说的是——openssl 的人都是十足的土包子。这不是一个玩具程序,它不是一个计算器或某种游戏,说真的......像我这样的人有用这个程序加密的重要内容。财务和法律方面的事情!因此,当我几年前突然需要加密文档而不是文档,或者至少信息“使用版本 X 的 openssl 进行解密”时,我会收到一些愚蠢的“解密错误”消息,就像心脏病发作一样。 (2认同)

Jay*_*Jay 10

我认为使用命令行进行加密的Key和IV使用你的程序是不一样的.

请注意,当您使用"-k"(不同于"-K")时,给定的输入被视为从中派生密钥的密码.通常在这种情况下,不需要"-iv"选项,因为密钥和密码都将从"-k"选项给出的输入中派生.

从您的问题来看,您不清楚如何确保密钥和IV在加密和解密之间是相同的.

在我的建议中,最好使用"-K"和"-iv"选项在加密期间明确指定密钥和IV,并使用相同的方法进行解密.如果需要使用"-k",则使用"-p"选项打印密钥,使用iv进行加密,并在解密程序中使用相同的密码.

有关详细信息,访问https://www.openssl.org/docs/manmaster/apps/enc.html


RAM*_*237 8

当您指定不正确的解密密码时,也会出现此消息(是的,很蹩脚,但从错误消息中不太明显地意识到这一点,是吧?)。

我正在使用命令行解密辅助工具的最新数据库备份,突然遇到了这个问题。

最后,经过 10 分钟的悲伤并阅读了这个问题/答案,我记起了密码是不同的,并且使用正确的密码一切都工作正常。


小智 7

在使用openssl命令行界面时,我遇到了类似的错误回复,同时具有正确的二进制密钥(-K)。选项“ -nopad”解决了该问题:

生成错误的示例:

echo -ne "\x32\xc8\xde\x5c\x68\x19\x7e\x53\xa5\x75\xe1\x76\x1d\x20\x16\xb2\x72\xd8\x40\x87\x25\xb3\x71\x21\x89\xf6\xca\x46\x9f\xd0\x0d\x08\x65\x49\x23\x30\x1f\xe0\x38\x48\x70\xdb\x3b\xa8\x56\xb5\x4a\xc6\x09\x9e\x6c\x31\xce\x60\xee\xa2\x58\x72\xf6\xb5\x74\xa8\x9d\x0c" | openssl aes-128-cbc -d -K 31323334353637383930313233343536 -iv 79169625096006022424242424242424 | od -t x1
Run Code Online (Sandbox Code Playgroud)

结果:

bad decrypt
140181876450560:error:06065064:digital envelope 
routines:EVP_DecryptFinal_ex:bad decrypt:../crypto/evp/evp_enc.c:535:
0000000 2f 2f 07 02 54 0b 00 00 00 00 00 00 04 29 00 00
0000020 00 00 04 a9 ff 01 00 00 00 00 04 a9 ff 02 00 00
0000040 00 00 04 a9 ff 03 00 00 00 00 0d 79 0a 30 36 38
Run Code Online (Sandbox Code Playgroud)

结果正确的示例:

echo -ne "\x32\xc8\xde\x5c\x68\x19\x7e\x53\xa5\x75\xe1\x76\x1d\x20\x16\xb2\x72\xd8\x40\x87\x25\xb3\x71\x21\x89\xf6\xca\x46\x9f\xd0\x0d\x08\x65\x49\x23\x30\x1f\xe0\x38\x48\x70\xdb\x3b\xa8\x56\xb5\x4a\xc6\x09\x9e\x6c\x31\xce\x60\xee\xa2\x58\x72\xf6\xb5\x74\xa8\x9d\x0c" | openssl aes-128-cbc -d -K 31323334353637383930313233343536 -iv 79169625096006022424242424242424 -nopad | od -t x1
Run Code Online (Sandbox Code Playgroud)

结果:

0000000 2f 2f 07 02 54 0b 00 00 00 00 00 00 04 29 00 00
0000020 00 00 04 a9 ff 01 00 00 00 00 04 a9 ff 02 00 00
0000040 00 00 04 a9 ff 03 00 00 00 00 0d 79 0a 30 36 38
0000060 30 30 30 34 31 33 31 2f 2f 2f 2f 2f 2f 2f 2f 2f
0000100
Run Code Online (Sandbox Code Playgroud)


小智 7

错误:“加密/解密错误”“gitencrypt_smudge:失败:openssl 解密文件时出错”

openssl 会抛出各种错误字符串,具体取决于各自的版本和场景。以下是我在处理 openssl 相关问题时使用的清单:

  1. 理想情况下,openssl 只能使用相同的密钥 (+ salt) 和 enc 算法进行加密/解密。
  2. 确保 openssl 版本(用于加密/解密)兼容。例如。openssl 中使用的哈希在 1.1.0 版中从 MD5 更改为 SHA256。这会根据相同的密码生成不同的密钥。修复:1.1.0加“-md md5”对低版本数据解密,低版本加“-md sha256”对1.1.0数据解密

  3. 确保您的机器上安装了一个 openssl 版本。如果同时安装了多个版本(在我的机器上,它们安装了:-“LibreSSL 2.6.5”和“openssl 1.1.1d”),请确保只有所需的版本出现在您的 PATH 变量中。


小智 7

您应该使用解密的私钥。例如:youprivatekey.decrypted.key。您可以运行此命令来解密您的私钥文件。

openssl rsa -in <encrypted_private.key> -out <decrypted_private.key>

Enter password:

Enter pass phrase for encrypted_private.key: <enter the password>

Wait:

writing RSA key

it's done...
Run Code Online (Sandbox Code Playgroud)