Reputation: 77
So this is my very first time dabbling with AES encryption and OpenSSL. I have managed to get some examples of encryption and decryption, but they don't seem to work properly. For one, in the encryption function:
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);
}
This generates an actual "encrypted" file which is not half bad but it's not exactly what it's supposed to be (or I think so). If I run the cli command from openssl to encrypt that same file, I get in return a text file which has encrypted strings written inside. The one made by my function is a file which is not text (actually it says it is unkown format).
The second one, the decryption:
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);
}
In this function I actually get an error: EVP_DecryptFinal() error: error:0606506D:digital envelope routines:EVP_DecryptFinal_ex:wrong final block lengthP
Now, not sure if the problem is just in decryption because of the error, or also encryption.
Also, my main:
// 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);
Also, strangely enough, if my file is strictly a text file, it works (even though it should normally encrypt any type of file).
Upvotes: 3
Views: 373
Reputation: 223689
Your calls to EVP_EncryptFinal
and EVP_DecryptFinal
are not writing to the correct place. Both write to outD
, which is the beginning of the buffer. These need to write to the end of the buffer, i.e. out
bytes later:
if(!EVP_EncryptFinal(ctx,outD+out,&out2))
...
if(!EVP_DecryptFinal(ctx,outD+out,&out2))
You're also not writing the correct number of bytes to the output files in both cases. The encrypted size is typically longer than the input size due to padding, but you're writing fsize
bytes, which is the size of the input file. You want the number of bytes written, i.e. out+out2
:
fwrite(outD,sizeof(char),out+out2,oF);
...
fwrite(outD,sizeof(char),out+out2,oF);
There's also an IV mismatch. For encryption you use "dontusethisinput" while for decryption you use "djntusethisinput" (note the second letter in each). These need to be the same.
You should also check the return values of the functions doing file I/O in case they don't work as expected, and also free
any dynamically allocated memory.
Upvotes: 1