C++ AES расшифровать в памяти

Я пытаюсь в Linux C++ загрузить зашифрованный двоичный файл AES256 в память и расшифровать в памяти без записи в HD. Это потому, что у меня есть некоторые разумные данные для защиты по соображениям конфиденциальности, и поэтому я не могу записать их или временно на диск.

Чтобы зашифровать файл, я использую этот код, найденный здесь на stackru:

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <openssl/evp.h>
#include <openssl/aes.h>

#ifndef TRUE
#define TRUE 1
#endif

#ifndef FALSE
#define FALSE 0
#endif


/**
 * Encrypt or decrypt, depending on flag 'should_encrypt'
 */
void en_de_crypt(int should_encrypt, FILE *ifp, FILE *ofp, unsigned char *ckey, unsigned char *ivec) {

    const unsigned BUFSIZE=4096;
    unsigned char *read_buf = (unsigned char *) malloc(BUFSIZE);
    unsigned char *cipher_buf;
    unsigned blocksize;
    int out_len;
    EVP_CIPHER_CTX ctx;

    EVP_CipherInit(&ctx, EVP_aes_256_cbc(), ckey, ivec, should_encrypt);
    blocksize = EVP_CIPHER_CTX_block_size(&ctx);
    cipher_buf = (unsigned char *) malloc(BUFSIZE + blocksize);

    while (1) {

        // Read in data in blocks until EOF. Update the ciphering with each read.

        int numRead = fread(read_buf, sizeof(unsigned char), BUFSIZE, ifp);
        EVP_CipherUpdate(&ctx, cipher_buf, &out_len, read_buf, numRead);
        fwrite(cipher_buf, sizeof(unsigned char), out_len, ofp);
        if (numRead < BUFSIZE) { // EOF
            break;
        }
    }

    // Now cipher the final block and write it out.

    EVP_CipherFinal(&ctx, cipher_buf, &out_len);
    fwrite(cipher_buf, sizeof(unsigned char), out_len, ofp);

    // Free memory

    free(cipher_buf);
    free(read_buf);
}

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

    unsigned char ckey[] = "thiskeyisverybad";
    unsigned char ivec[] = "dontusethisinput";
    FILE *fIN, *fOUT;

    /*
    if (argc != 2) {
        printf("Usage: <executable> /path/to/file/exe");
        return -1;
    }
    */


    // Decrypt

    fIN = fopen( argv[ 1 ], "rb" ); //File to be encrypted; plain text
    fOUT = fopen( argv[ 2 ], "wb" ); //File to be written; cipher text

    en_de_crypt( TRUE, fIN, fOUT, ckey, ivec );

    fclose( fIN );
    fclose( fOUT );

    return 0;
}

Этот скрипт правильно шифрует и дешифрует с помощью AES 256. Я использую его для шифрования моих разумных данных. С другой стороны, я пытаюсь загрузить файл в векторе неподписанного символа в памяти следующим образом:

const unsigned BUFSIZE = 4096;    
unsigned char ckey[] = "thiskeyisverybad";
unsigned char ivec[] = "dontusethisinput";
unsigned blocksize;
int out_len;
EVP_CIPHER_CTX ctx;

std::vector<unsigned char>fileDecrypted;
FILE * fileToDecrypt = NULL;
unsigned char *read_buf = (unsigned char *) malloc(BUFSIZE);
unsigned char *cipher_buf;
size_t bytesRead = 0;

fileToDecrypt = fopen( filename, "rb" );   

EVP_CipherInit(&ctx, EVP_aes_256_cbc(), ckey, ivec, FALSE );
blocksize = EVP_CIPHER_CTX_block_size(&ctx);
cipher_buf = (unsigned char *) malloc(BUFSIZE + blocksize);


if ( fileToDecrypt != NULL ) {
    // read up to sizeof(buffer) bytes
    while (( bytesRead = fread( read_buf, 1, BUFSIZE, fileToDecrypt )) > 0 ) {
        // process bytesRead worth of data in buffer
        EVP_CipherUpdate(&ctx, cipher_buf, &out_len, read_buf, bytesRead);
        fileDecrypted.push_back( *cipher_buf );
        if (bytesRead < BUFSIZE) { // EOF
            break;
        }            
    }
}

EVP_CipherFinal(&ctx, cipher_buf, &out_len);
fileDecrypted.push_back( *cipher_buf );

free(cipher_buf);
free(read_buf); 

long int sizeFileDecrypted = ( long int ) ( sizeof( std::vector<unsigned char> ) + ( sizeof( unsigned char ) * fileDecrypted.size() ) );
google::protobuf::io::ArrayInputStream arr( reinterpret_cast<char*>(fileDecrypted.data()), sizeFileDecrypted ); 

Окончательный расшифрованный код в памяти должен быть передан в google protobuf ArrayInputStream. Кажется, что файл загружен и расшифрован правильно, но он создает ошибки при следующем разборе проверенного и отлаженного кода, который обычно запускается без проблем. Фактически, когда я пытаюсь загрузить обычный файл (незашифрованный файл), я могу достичь цели просто так:

// Reading size of file
FILE * file = fopen( filename, "r+");
// if (file == NULL) return;
fseek(file, 0, SEEK_END);
long int sizef = ftell(file);
fclose(file);
// Reading data to array of unsigned chars
file = fopen( filename, "r+");
unsigned char * in = (unsigned char *) malloc(sizef);
int bytes_read = fread(in, sizeof(unsigned char), sizef, file);
fclose(file);
google::protobuf::io::ArrayInputStream arr( in, sizef );

Кто-нибудь может помочь мне правильно достичь цели? Я не программист C++, но я должен сделать этот кусок кода на этом языке, и это не просто. Спасибо Лоренцо

0 ответов

Другие вопросы по тегам