【问题标题】:OpenSSL AES encryption doesn't seem to work properlyOpenSSL AES 加密似乎无法正常工作
【发布时间】:2019-01-26 01:51:20
【问题描述】:

所以这是我第一次涉足 AES 加密和 OpenSSL。我已经设法获得了一些加密和解密的示例,但它们似乎无法正常工作。一,在加密函数中:

void encryptAES(FILE *iF, FILE *oF)
{
    fseek(iF, 0L, SEEK_END);
    int fsize = ftell(iF);
    fseek(iF, 0L, SEEK_SET);

    int out = 0; 
    int out2 = 0;
    unsigned char *inD = ( unsigned char * )malloc(fsize);
    unsigned char *outD = ( unsigned char * )malloc(fsize*2);
    unsigned char ckey[] =  "thiskeyisverybad";
    unsigned char ivec[] = "dontusethisinput";

    fread(inD,sizeof(char),fsize, iF);

    EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new();

    if(!EVP_EncryptInit(ctx,EVP_aes_128_cbc(),ckey,ivec))
    {
        std::cout<<"EVP_EncryptInit() error: "<<ERR_error_string(ERR_get_error(), NULL);
    }

    if(!EVP_EncryptUpdate(ctx,outD,&out,inD,fsize))
    {
        std::cout<<"EVP_EncryptUpdate() error: "<<ERR_error_string(ERR_get_error(), NULL);
    }

    if(!EVP_EncryptFinal(ctx,outD,&out2))
    {
        std::cout<<"EVP_EncryptFinal() error: "<<ERR_error_string(ERR_get_error(), NULL);
    }

    fwrite(outD,sizeof(char),fsize,oF);
}

这会生成一个实际的“加密”文件,该文件还不错,但并不完全是它应该是的(或者我认为如此)。如果我从 openssl 运行 cli 命令来加密同一个文件,我会返回一个文本文件,其中写入了加密的字符串。我的函数生成的文件是一个不是文本的文件(实际上它说它是未知格式)。

第二个,解密:

void decryptAES(FILE *iF, FILE *oF)
{
    fseek(iF, 0L, SEEK_END);
    int fsize = ftell(iF);
    fseek(iF, 0L, SEEK_SET);

    int out = 0;
    int out2 = 0;
    unsigned char *inD = ( unsigned char * )malloc(fsize);
    unsigned char *outD = ( unsigned char * )malloc(fsize*2);
    unsigned char ckey[] =  "thiskeyisverybad";
    unsigned char ivec[] = "djntusethisinput";

    fread(inD,sizeof(char),fsize, iF);//Read Entire File

    EVP_CIPHER_CTX * ctx = EVP_CIPHER_CTX_new();

    if(!EVP_DecryptInit(ctx,EVP_aes_128_cbc(),ckey,ivec))
    {
        std::cout<<"EVP_DecryptInit() error: "<<ERR_error_string(ERR_get_error(), NULL);
    }

    if(!EVP_DecryptUpdate(ctx,outD,&out,inD,fsize))
    {
        std::cout<<"EVP_DecryptUpdate() error: "<<ERR_error_string(ERR_get_error(), NULL);
    }

    if(!EVP_DecryptFinal(ctx, outD, &out2))
    {
        std::cout<<"EVP_DecryptFinal() error: "<<ERR_error_string(ERR_get_error(), NULL);
    }
    fwrite(outD,sizeof(char),fsize,oF);
}

在这个函数中我实际上得到了一个错误:EVP_DecryptFinal() error: error:0606506D:digital envelope routines:EVP_DecryptFinal_ex:wrong final block lengthP

现在,不确定问题是否只是由于错误导致的解密,还是加密。

还有,我的主要:

// Encrypt

FILE *ifp = fopen("Test.zip", "rb");
FILE *ofp = fopen("Test.zip.enc", "wb");

encryptAES(ifp, ofp);

fclose(ifp);
fclose(ofp);

// Decrypt

FILE *iF = fopen("Test.zip.enc", "rb");
FILE *oF = fopen("TEST.zip", "wb");

decryptAES(ifP, ofP);

fclose(iF);
fclose(oF);

另外,奇怪的是,如果我的文件是严格的文本文件,它可以工作(即使它通常应该加密任何类型的文件)。

【问题讨论】:

  • 此代码无法编译。所有函数中都有几个未定义的变量(infileoutfileifPofP 等)。请复制并粘贴导致问题的实际代码。
  • 有几个变量名称已过时。现在这正是它为我编译的方式。

标签: c++ encryption openssl aes


【解决方案1】:

您对EVP_EncryptFinalEVP_DecryptFinal 的调用没有写入正确的位置。两者都写入outD,这是缓冲区的开始。这些需要写入缓冲区的end,即out字节后:

if(!EVP_EncryptFinal(ctx,outD+out,&out2))
...
if(!EVP_DecryptFinal(ctx,outD+out,&out2))

在这两种情况下,您也没有将正确数量的字节写入输出文件。由于填充,加密大小通常比输入大小长,但您正在写入 fsize 字节,这是输入文件的大小。您想要写入的字节数,即out+out2

fwrite(outD,sizeof(char),out+out2,oF);
...
fwrite(outD,sizeof(char),out+out2,oF);

还有一个 IV 不匹配。对于加密,您使用“dontusethisinput”,而对于解密,您使用“djntusethisinput”(注意每个中的第二个字母)。这些必须相同。

您还应该检查执行文件 I/O 的函数的返回值,以防它们无法按预期工作,还应该检查 free 任何动态分配的内存。

【讨论】:

  • 哦,我现在明白了。这说得通。一般来说,我有点不得不习惯 AES 和 OpenSSL,但现在我有了一个工作示例,我可以更好地检查它。感谢您的宝贵时间。
猜你喜欢
  • 2023-04-03
  • 1970-01-01
  • 2017-09-04
  • 2012-05-06
  • 2013-02-17
  • 2017-10-09
  • 2017-08-03
  • 2014-05-02
  • 2011-09-11
相关资源
最近更新 更多