Skip to content

Instantly share code, notes, and snippets.

@chaoaero
Created June 29, 2016 09:11
Show Gist options
  • Save chaoaero/a35506d7a46d1b11b650ae74adfaac1f to your computer and use it in GitHub Desktop.
Save chaoaero/a35506d7a46d1b11b650ae74adfaac1f to your computer and use it in GitHub Desktop.
#include "thirdparty/glog/logging.h"
#include <string.h>
namespace chaoaero
{
// ecb mode with no padding
// no need to append '\0' when the length of input text is not multiple of the block size
Aes128::Aes128(const std::string& key_data)
{
int key_len = key_data.size();
CHECK_EQ(kKeyLength, key_len)
<< "key size should be 128 bits but" << key_len;
for(int i=0;i< key_len; i++)
m_key[i] = key_data[i];
EVP_CIPHER_CTX_init(&m_encoder);
EVP_EncryptInit_ex(&m_encoder, EVP_aes_128_ecb(), NULL,reinterpret_cast<const unsigned char*>(key_data.c_str()) , m_iv);
// set no padding for encode
EVP_CIPHER_CTX_set_padding(&m_encoder, 0);
EVP_CIPHER_CTX_init(&m_decoder);
EVP_DecryptInit_ex(&m_decoder, EVP_aes_128_ecb(), NULL, reinterpret_cast<const unsigned char*>(key_data.c_str()), m_iv);
// set no padding for decode
EVP_CIPHER_CTX_set_padding(&m_decoder, 0);
}
Aes128::~Aes128()
{
EVP_CIPHER_CTX_cleanup(&m_encoder);
EVP_CIPHER_CTX_cleanup(&m_decoder);
}
bool Aes128::Encode(const std::string& plain_text, std::string* cipher_text)
{
if(cipher_text == NULL)
return false;
int input_len = plain_text.size();
int residual = input_len % 16;
if(residual != 0)
input_len = input_len - residual + 16;
cipher_text->resize(input_len);
// Allows reusing of m_encoder for multiple encryption cycles.
EVP_EncryptInit_ex(&m_encoder, NULL, NULL, NULL, NULL);
int len = 0;
unsigned char block_str[input_len];
for(int i = 0; i< plain_text.size(); i++)
block_str[i] = plain_text[i];
for(int i = plain_text.size(); i < input_len ;i++)
block_str[i] = 0x00;
EVP_EncryptUpdate(
&m_encoder,
reinterpret_cast<unsigned char*>(&(*cipher_text)[0]),
&len,
block_str,
//reinterpret_cast<const unsigned char*>(block_str.c_str()),
input_len);
CHECK_LE(len, cipher_text->size())
<< "buffer length is less or equal to the length of encrypted text";
// Update cipher_text with the final remaining bytes.
int last_block_len = 0;
EVP_EncryptFinal_ex(
&m_encoder,
reinterpret_cast<unsigned char*>(&(*cipher_text)[len]),
&last_block_len);
cipher_text->resize(len + last_block_len);
return true;
}
bool Aes128::Decode(const std::string& cipher_text, std::string* plain_text)
{
if(plain_text == NULL)
return false;
int input_len = cipher_text.size();
int residual = input_len % 16;
if(residual != 0)
input_len = input_len - residual + 16;
plain_text->resize(input_len);
EVP_DecryptInit_ex(&m_decoder, NULL, NULL, NULL, NULL);
int len = 0;
EVP_DecryptUpdate(
&m_decoder,
reinterpret_cast<unsigned char*>(&(*plain_text)[0]),
&len,
reinterpret_cast<const unsigned char*>(cipher_text.c_str()),
input_len);
CHECK_LE(len, plain_text->size())
<< "buffer length is less or equal to plain text length";
// Update plain_text with the final remaining bytes.
int last_block_len = 0;
EVP_DecryptFinal_ex(
&m_decoder,
reinterpret_cast<unsigned char*>(&(*plain_text)[len]),
&last_block_len);
int final_len = len + last_block_len;
int rstrip = 0;
plain_text->resize(len + last_block_len);
for(int i= final_len - 1; i> 0 ;i--){
if((*plain_text)[i] == 0x00)
rstrip++;
else
break;
}
plain_text->resize(final_len - rstrip);
return true;
}
}
/*==================================================================
* Copyright (C) 2015 All rights reserved.
*
* filename: aes.h
* author: Meng Weichao
* created: 2015/07/30
* description:
*
================================================================*/
#ifndef __AES_H__
#define __AES_H__
#include <string>
#include "common/base/stdint.h"
#include "common/base/uncopyable.h"
#include "thirdparty/openssl/aes.h"
#include "thirdparty/openssl/evp.h"
namespace chaoaero
{
class Aes128: private Uncopyable
{
public:
// @key_data: used for initialzed the encryption key
explicit Aes128(const std::string& key_data);
~Aes128();
bool Encode(const std::string& plain_text, std::string* cipher_text);
bool Decode(const std::string& cipher_text, std::string* plain_text);
private:
static const int kKeyLength = 16;
EVP_CIPHER_CTX m_encoder;
EVP_CIPHER_CTX m_decoder;
unsigned char m_key[kKeyLength];
unsigned char m_iv[kKeyLength];
};
}
#endif //__AES_H__
@chaoaero
Copy link
Author

openssl AES C++ wrapper

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment