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也是一样。
我最近开始使用 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也是一样。