问题描述
我有OpenSSL AES的问题(我使用aes.h):
I have problem with OpenSSL AES ( I use aes.h ) :
-
获取二进制文件
get binary file (.pdf , .jpg ) or some .xml , .txt about 5000 chars , then i enrypt base64.
当我尝试enrypt AES时,我得到了不好的大小(随机400,200 ,50),my AESKey is random 128bits from chars:[abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789,.- @#& *oeOE¯_]
When I try enrypt AES i get bad size ( Random 400 , 200 , 50 ) , my AESKey is random 128bits from chars : [abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 ,.-@#&*oeOE¯_ ]
我认为问题是'\0'enrypted char,但我不知道我可以extort条目
(字符串可以保存的字符数组与\0元素,但unsigned char *和char *中止)
I think that problem is '\0' enrypted char but i don't know can I extort entry(string can save char array with \0 element but unsigned char* and char* is aborted )
这是我的代码:
std::string PFHelper::ASE_encode(std::string in, wchar_t* KS)
{
//const unsigned char* aes_input = reinterpret_cast<const unsigned char *> (in.c_str());
unsigned char* aes_input = new unsigned char[in.length()];
strcpy((char*)aes_input, in.c_str());
std::string KS_string = PFHelper::ConvertFromUtf8ToString(KS);
unsigned char* aes_key = new unsigned char[16];
strcpy((char*)aes_key, KS_string.c_str());
/* Input data to encrypt */
unsigned char iv[AES_BLOCK_SIZE];
memset(iv, 0x00, AES_BLOCK_SIZE);
const size_t encslength = ((in.length() + AES_BLOCK_SIZE) / AES_BLOCK_SIZE) * AES_BLOCK_SIZE;
/* Buffers for Encryption and Decryption */
unsigned char * enc_out = new unsigned char [encslength];
//unsigned char * dec_out = new unsigned char[in.length()];
memset(enc_out, 0, encslength);
//memset(dec_out, 0, in.length());
AES_KEY enc_key;
AES_set_encrypt_key(aes_key, 128, &enc_key);
AES_cbc_encrypt(aes_input, enc_out, encslength, &enc_key, iv, AES_ENCRYPT);
//AES_KEY decrypt;
//memset(iv, 0x00, AES_BLOCK_SIZE);
//AES_cbc_encrypt((unsigned char*)enc_out, dec_out, encslength, &decrypt, iv, AES_DECRYPT);
//std::string returned = ConvertFromUnsignedCharToString(enc_out);
memset(aes_key, 0x00, 16);
memset(aes_input, 0x00, in.length());
return ConvertFromUnsignedCharToString(enc_out);
}
示例值:
KS(AESKey):LF-ZTNW meOJLK1s5
KS (AESKey) : L"F-ZTNW meOJLK1s5"
in(5464chars):PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVR .....
in(5464chars) : PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVR.....
out(51chars):©|ľ'Ň·rnoŚ8nžęwřëůlěyßJ2¨ßňO×ohX,Ž〜ŚČE
out(51chars) : "©¦ľ‘Ň·rnoŚ8nžęwřëůl2ěY ßJ2¨ßňO× ohX‚Ž~ŚČ"E
我尝试EVP和典型的char键和问题是一样的
I try EVP and typical char key and problem is the same
//set back to normal
unsigned char* aes_input = new unsigned char[in.length()];
strcpy((char*)aes_input, in.c_str());
unsigned char* dec_out = new unsigned char[in.length()];
memset(dec_out, 0, in.length());
dec_out[in.length()] = '\0';
/* A 256 bit key */
unsigned char *key = (unsigned char *)"01234567890123456789012345678901";
/* A 128 bit IV */
unsigned char *iv = (unsigned char *)"01234567890123456";
int lenght;
int c_len = in.length() + AES_BLOCK_SIZE;
//Set up encryption
int f_len = 0;
EVP_CIPHER_CTX *ctx;
ctx = EVP_CIPHER_CTX_new();
if (EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv) != 1)
{
wcout << L"1";
}
if (EVP_EncryptUpdate(ctx, dec_out, &lenght, aes_input, in.length()) != 1)
{
wcout << L"2";
}
if (EVP_EncryptFinal_ex(ctx, dec_out, &lenght) != 1)
{
wcout << L"3";
}
return ConvertFromUnsignedCharToString(dec_out);
}
推荐答案
在使用OpenSSL的EVP接口时使用 std :: strings
管理缓冲区。它也避免了你正在做的额外复制。您仍然需要改善键控策略。
Here's an example which demonstrates how to use std::strings
to manage buffers while using OpenSSL's EVP interfaces. It also avoids the extra copying you are doing. You still need to improve your keying strategy.
您应该提供一个零化分配器。您应该考虑。
You should provide a zeroize'ing allocator. You should consider an Authenticated Encryption mode.
使用 g ++ -std = c ++ 11 test.cxx -o test.exe -lcrypto
编译它。
#include <iostream>
#include <string>
#include <memory>
#include <stdexcept>
using namespace std;
#include <openssl/evp.h>
#include <openssl/rand.h>
static const unsigned int KEY_SIZE = 16;
static const unsigned int BLOCK_SIZE = 16;
typedef unsigned char byte;
using EVP_CIPHER_CTX_free_ptr = std::unique_ptr<EVP_CIPHER_CTX, decltype(&::EVP_CIPHER_CTX_free)>;
void gen_keys(byte key[KEY_SIZE], byte iv[BLOCK_SIZE]);
void encrypt(const byte key[KEY_SIZE], const byte iv[BLOCK_SIZE], const string& ptext, string& ctext);
void decrypt(const byte key[KEY_SIZE], const byte iv[BLOCK_SIZE], const string& ctext, string& rtext);
int main(int argc, char* argv[])
{
// plaintext, ciphertext, recovered text
string ptext = "Now is the time for all good men to come to the aide of their country";
string ctext, rtext;
byte key[KEY_SIZE], iv[BLOCK_SIZE];
gen_keys(key, iv);
encrypt(key, iv, ptext, ctext);
decrypt(key, iv, ctext, rtext);
cout << "Recovered message:\n" << rtext << endl;
return 0;
}
void gen_keys(byte key[KEY_SIZE], byte iv[BLOCK_SIZE])
{
int rc = RAND_bytes(key, KEY_SIZE);
if (rc != 1)
throw runtime_error("RAND_bytes key failed");
rc = RAND_bytes(iv, BLOCK_SIZE);
if (rc != 1)
throw runtime_error("RAND_bytes for iv failed");
}
void encrypt(const byte key[KEY_SIZE], const byte iv[BLOCK_SIZE], const string& ptext, string& ctext)
{
EVP_CIPHER_CTX_free_ptr ctx(EVP_CIPHER_CTX_new(), ::EVP_CIPHER_CTX_free);
int rc = EVP_EncryptInit_ex(ctx.get(), EVP_aes_128_cbc(), NULL, key, iv);
if (rc != 1)
throw runtime_error("EVP_EncryptInit_ex failed");
// Cipher text will be upto 16 bytes larger than plain text
ctext.resize(ptext.size()+16);
int out_len1 = (int)ctext.size();
rc = EVP_EncryptUpdate(ctx.get(), (byte*)&ctext[0], &out_len1, (const byte*)&ptext[0], (int)ptext.size());
if (rc != 1)
throw runtime_error("EVP_EncryptUpdate failed");
int out_len2 = (int)ctext.size() - out_len1;
rc = EVP_EncryptFinal_ex(ctx.get(), (byte*)&ctext[0]+out_len1, &out_len2);
if (rc != 1)
throw runtime_error("EVP_EncryptFinal_ex failed");
ctext.resize(out_len1 + out_len2);
}
void decrypt(const byte key[KEY_SIZE], const byte iv[BLOCK_SIZE], const string& ctext, string& rtext)
{
EVP_CIPHER_CTX_free_ptr ctx(EVP_CIPHER_CTX_new(), ::EVP_CIPHER_CTX_free);
int rc = EVP_DecryptInit_ex(ctx.get(), EVP_aes_128_cbc(), NULL, key, iv);
if (rc != 1)
throw runtime_error("EVP_DecryptInit_ex failed");
// Recovered text will be smaller than cipher text, not larger
rtext.resize(ctext.size());
int out_len1 = (int)rtext.size();
rc = EVP_DecryptUpdate(ctx.get(), (byte*)&rtext[0], &out_len1, (const byte*)&ctext[0], (int)ctext.size());
if (rc != 1)
throw runtime_error("EVP_DecryptUpdate failed");
int out_len2 = (int)rtext.size() - out_len1;
rc = EVP_DecryptFinal_ex(ctx.get(), (byte*)&rtext[0]+out_len1, &out_len2);
if (rc != 1)
throw runtime_error("EVP_DecryptFinal_ex failed");
rtext.resize(out_len1 + out_len2);
}
这篇关于OpenSSL AES 128 CBC \0崩溃加密char *的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!