Search code examples
openssl

OpenSSL C Api decrypting file produces garbage bytes instead of expected text


I've recently started using OpenSSL and I'm having trouble programming with the C API.

I encrypted a file with a key and an iv using the command line tool just fine :

openssl enc -p -in Logs.txt -out Logs.enc -e -aes256 -K 12345 -iv 174a76
hex string is too short, padding with zero bytes to length
hex string is too short, padding with zero bytes to length
salt=0000000000000000
key=1234500000000000000000000000000000000000000000000000000000000000
iv =174A7600000000000000000000000000

Now i'm trying to decrypt my file using the C API but the output string has garbage bytes instead of the expected text , I don't know what I'm doing wrong.

Here is my code :

#include <string>
#include <fstream>

#include <openssl/ssl.h>

#include <iostream>
#include <vector>
#include <locale>
#include <windows.h>


int decrypt(unsigned char* ciphertext, int ciphertext_len, unsigned char* key,
    unsigned char* iv, unsigned char* plaintext)
{
    EVP_CIPHER_CTX* ctx;

    int len;

    int plaintext_len;

    /* Create and initialise the context */
    if (!(ctx = EVP_CIPHER_CTX_new())) return -1;

    /*
     * Initialise the decryption operation. IMPORTANT - ensure you use a key
     * and IV size appropriate for your cipher
     * In this example we are using 256 bit AES (i.e. a 256 bit key). The
     * IV size for *most* modes is the same as the block size. For AES this
     * is 128 bits
     */
    if (1 != EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv))
        return -1;

    /*
     * Provide the message to be decrypted, and obtain the plaintext output.
     * EVP_DecryptUpdate can be called multiple times if necessary.
     */
    if (1 != EVP_DecryptUpdate(ctx, plaintext, &len, ciphertext, ciphertext_len))
        return -1;
    plaintext_len = len;

    /*
     * Finalise the decryption. Further plaintext bytes may be written at
     * this stage.
     */
    if (1 != EVP_DecryptFinal_ex(ctx, plaintext + len, &len))
        return -1;
    plaintext_len += len;

    /* Clean up */
    EVP_CIPHER_CTX_free(ctx);

    return plaintext_len;
}

int main() {
    // Set Key and Iv 
    unsigned char* key = (unsigned char*)"1234500000000000000000000000000000000000000000000000000000000000";
    unsigned char* iv = (unsigned char*)"174A7600000000000000000000000000";

    // Get Data from encrypted file
    std::ifstream enc("Logs.enc",std::ios::binary);
    std::string data = std::string((std::istreambuf_iterator<char>(enc)), std::istreambuf_iterator<char>());
    unsigned char* __data__ = (unsigned char*)data.c_str();
    int data_l = data.size();


    // Displays garbage bytes in output "dec"
    unsigned char dec[4096] = "";
    decrypt(__data__,data_l,key,iv,dec);
}

Most of my code has come from examples I've seen from the OpenSSL wiki page

I will appreciate any help.

Thank you

Edit :

It worked , thanks Matt Casswell for helping me , turns out I needed to change the key and iv value to be hex values :

 unsigned char key[] = {0x12,0x34,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
    unsigned char iv[] = {0x17,0x4A,0x76,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

Solution

  • key=1234500000000000000000000000000000000000000000000000000000000000

    This is a hex value with first byte of value 12 in hex (18 in decimal).

    unsigned char* key = (unsigned char*)"1234500000000000000000000000000000000000000000000000000000000000";

    This value is a string containing printable characters. The first byte is the printable character "1". The ASCII value for "1" is 31 in hex (49 decimal).

    So the key you passed on the command line does not match the key you are passing in your code. The same is true for the IV.