OpenSSL C Api 解密文件产生垃圾字节而不是预期的文本

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

我最近开始使用 OpenSSL,但在使用 C API 编程时遇到了问题。

我使用命令行工具用一个密钥和一个 iv 加密了一个文件就好了:

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

现在我正在尝试使用 C API 解密我的文件,但输出字符串有垃圾字节而不是预期的文本,我不知道我做错了什么。

这是我的代码:

#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);
}

我的大部分代码都来自我在 OpenSSL wiki 页面上看到的示例

如有任何帮助,我将不胜感激。

谢谢

编辑:

成功了,感谢 Matt Casswell 帮助我,结果我需要将密钥和 iv 值更改为十六进制值:

 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};

key=1234500000000000000000000000000000000000000000000000000000000000

这是一个十六进制值,第一个字节的十六进制值为 12(十进制为 18)。

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

这个值是一个包含可打印字符的字符串。第一个字节是可打印字符“1”。 “1”的 ASCII 值是十六进制的 31(十进制的 49)。

因此您在命令行中传递的密钥与您在代码中传递的密钥不匹配。 IV也是一样。