OpenSSL AES加密似乎无法正常工作

时间:2018-08-19 22:01:30

标签: c++ encryption openssl aes

所以这是我第一次尝试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);

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

1 个答案:

答案 0 :(得分: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不匹配。对于加密,请使用“ d o ntusethisinput”,而对于解密,请使用“ d j ntusethisinput”(请注意每个字母的第二个字母)。这些必须相同。

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