使用C ++中的EVP API使用OpenSSL进行的AES CBC 128位解密失败

时间:2019-09-04 10:15:02

标签: c++ encryption openssl

您好,我有一组数据向量std::vector<uint8_t>,我需要使用AES CBC 128进行加密,为此,我尝试使用通过EVP API的OpenSSL AES CBC 128。但是由于某种原因,我无法解密数据。如控制台输出所示:

$ ./a.out 
Original data: b25f6a3f71a9285
Data before encryption b25f6a3f71a9285
Data after encryption bceb55ccb26d83b02d63ff785e538af000000000
Data was encrypted moving on to decryption
Origninal data after decryption b25f6a3f71a9285
data after decryption e7fc6fdb4f9aa50cfb46764c04010fb000000000
[Failure] we failed data is not decrypted```

但是,我找不到我在代码中的错误地方。

这是我一直在使用的最低限度示例:


#include <vector>
#include <cstdint>

#include <algorithm>
#include <ctime>
#include <cassert>

#include <openssl/aes.h>
#include <openssl/evp.h>

#include <iostream>

#include <utility>
#include <sstream>

void print_data(const std::vector<uint8_t> data)
{
    std::stringstream ss; 
    for (const auto& elm : data)
    {
        ss << std::hex << (int)elm; 
    }
    std::cout << ss.str() << std::endl; ; 
}

std::vector<uint8_t> generate_data(size_t size)
{
    srand(static_cast<uint32_t>(time(0)));

    std::vector<uint8_t> data(size);
    std::generate(data.begin(), data.end(), rand);
    return data; 
}

void aes_128_cbc_init_cryptert(EVP_CIPHER_CTX* crypter_context, const std::string& key, bool decrypter=false)
{
    unsigned char aes_key[key.size()];
    strcpy((char*) aes_key, key.c_str()); 

    std::vector<uint8_t> iv(AES_BLOCK_SIZE, 0);

    EVP_CIPHER_CTX_init(crypter_context);
    if (decrypter)
    {
        EVP_DecryptInit_ex(crypter_context, EVP_aes_128_cbc(), NULL, aes_key, iv.data());
    }
    else
    {
        EVP_EncryptInit_ex(crypter_context, EVP_aes_128_cbc(), NULL, aes_key, iv.data());
    }

}


void encrypt(const std::string& key, std::vector<uint8_t>& data)
{

    // Maximum lenghter of cipher is data.sizE() + AES_BLOCK_SIZE - 1 
    int cipher_length = data.size() + 1 + AES_BLOCK_SIZE;
    int final_length = 0;
    int data_length = static_cast<int>(data.size()); 

    std::vector<uint8_t> cipher(cipher_length, 0);

    EVP_CIPHER_CTX en;
    aes_128_cbc_init_cryptert(&en, key);

    EVP_EncryptUpdate(&en, cipher.data(), &cipher_length, data.data(), data_length);

    EVP_EncryptFinal_ex(&en, cipher.data()+cipher_length, &final_length);
    data = cipher;    
}

void decrypt(const std::string& key, std::vector<uint8_t>& data)
{
    // Will always be smaller that encrypted data
    int out_length = data.size();
    int final_length = 0;
    std::vector<uint8_t> out(out_length);

    EVP_CIPHER_CTX en;
    aes_128_cbc_init_cryptert(&en, key, true);
    EVP_DecryptUpdate(&en, out.data(), &out_length, data.data(), data.size());
    EVP_DecryptFinal_ex(&en, out.data()+out_length, &final_length);
    data = out; 
}


int main(void)
{
    std::string key = "7LVQ2YOYWI4AQNYC";

    std::vector<uint8_t> org_data = generate_data(8);

    std::cout << "Original data: "; 
    print_data(org_data);
    auto data = org_data;
    std::cout << "Data before encryption ";
    print_data(data); 
    encrypt(key, data);

    std::cout << "Data after encryption ";
    print_data(data); 
    if (data == org_data)
    {
        std::cout << "Data was not encrypted" << std::endl;
        return -1;
    }
    else
    {
        std::cout << "Data was encrypted moving on to decryption" << std::endl; 
    }

    decrypt(key, data);

    std::cout << "Origninal data after decryption ";
    print_data(org_data);
    std::cout << "data after decryption ";
    print_data(data);

    if (data == org_data)
    {
        std::cout << "[Success] Data was decrypted" << std::endl;
        return 0;
    }
    else
    {
        std::cout << "[Failure] we failed data is not decrypted" << std::endl;
        return - 1; 
    }
}

我认为这是因为我在解密的输入和输出大小或它自己的“解密程序”的初始化上做错了什么,但是我无法证实这一点。我一直在研究这个示例:https://github.com/saju/misc/blob/master/misc/openssl_aes.c

0 个答案:

没有答案