Add aes cbc module
This commit is contained in:
parent
7b01638c9f
commit
48b9f1b65e
@ -15,7 +15,7 @@ using std::pair;
|
||||
//提示信息打印类函数
|
||||
namespace Net {
|
||||
|
||||
namespace printTools {
|
||||
namespace PrintTools {
|
||||
|
||||
using FormalItem = pair<string, string>;
|
||||
|
||||
|
50
include/utils/aes_cbc_encryptor.h
Normal file
50
include/utils/aes_cbc_encryptor.h
Normal file
@ -0,0 +1,50 @@
|
||||
//
|
||||
// Created by 胡宇 on 2020/7/7.
|
||||
//
|
||||
|
||||
#ifndef NET_AES_CBC_ENCRYPTOR_H
|
||||
#define NET_AES_CBC_ENCRYPTOR_H
|
||||
|
||||
#include <cassert>
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <openssl/aes.h>
|
||||
#include <openssl/evp.h>
|
||||
|
||||
#include "debug_tools/print_tools.h"
|
||||
#include "random_generator.h"
|
||||
|
||||
namespace Net {
|
||||
|
||||
class AESCBCEncryptor {
|
||||
public:
|
||||
|
||||
AESCBCEncryptor() {
|
||||
generate_random_key_data();
|
||||
aes_init(key_data);
|
||||
}
|
||||
|
||||
string getKeyData() const{
|
||||
return key_data;
|
||||
}
|
||||
|
||||
void encrypt(const std::string &data, std::string &encrypted_data);
|
||||
|
||||
void decrypt(std::string &data, const std::string &encrypt_data);
|
||||
|
||||
private:
|
||||
const int nrounds = 8;
|
||||
uint8_t key[32], iv[32];
|
||||
EVP_CIPHER_CTX *e_ctx = EVP_CIPHER_CTX_new();
|
||||
|
||||
std::string key_data;
|
||||
|
||||
void generate_random_key_data();
|
||||
|
||||
void aes_init(std::string &key_data);
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif //NET_AES_CBC_ENCRYPTOR_H
|
30
include/utils/random_generator.h
Normal file
30
include/utils/random_generator.h
Normal file
@ -0,0 +1,30 @@
|
||||
//
|
||||
// Created by 胡宇 on 2020/7/7.
|
||||
//
|
||||
|
||||
#ifndef NET_RANDOM_GENERATOR_H
|
||||
#define NET_RANDOM_GENERATOR_H
|
||||
|
||||
#include <boost/random.hpp>
|
||||
#include <boost/random/random_device.hpp>
|
||||
|
||||
namespace Net{
|
||||
namespace Rand{
|
||||
|
||||
// 范围均匀分布无符号32位整数
|
||||
class UniformUInt {
|
||||
public:
|
||||
UniformUInt(uint32_t min, uint32_t max) : uniformInt(min, max){
|
||||
|
||||
}
|
||||
|
||||
int generate() const;
|
||||
private:
|
||||
boost::uniform_int<uint32_t> uniformInt;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif //NET_RANDOM_GENERATOR_H
|
@ -33,7 +33,7 @@ namespace Net {
|
||||
}
|
||||
|
||||
void printInfo(){
|
||||
printTools::printInfoFormal("RSAPubKey Info", {
|
||||
PrintTools::printInfoFormal("RSAPubKey Info", {
|
||||
{"n", this->n.getDataHex()},
|
||||
{"e", this->e.getDataHex()}
|
||||
});
|
||||
@ -62,7 +62,7 @@ namespace Net {
|
||||
}
|
||||
|
||||
void printInfo() const{
|
||||
printTools::printInfoFormal("RSAPrvKey Info", {
|
||||
PrintTools::printInfoFormal("RSAPrvKey Info", {
|
||||
{"n", this->n.getDataHex()},
|
||||
{"e", this->e.getDataHex()},
|
||||
{"d", this->d.getDataHex()},
|
||||
@ -102,13 +102,16 @@ namespace Net {
|
||||
this->if_prv_key = true;
|
||||
}
|
||||
|
||||
// 生成一对公私钥
|
||||
void generateKeyPair();
|
||||
|
||||
// 检查私钥是否合法
|
||||
bool checkKey();
|
||||
|
||||
// 公钥加密
|
||||
void publicKeyEncrypt(const string &data, string &encrypted_data);
|
||||
|
||||
// 私钥解密
|
||||
void privateKeyDecrypt(string &data, const string& encrypted_data);
|
||||
|
||||
uint32_t getBufferSize() const {
|
||||
|
@ -32,6 +32,7 @@ public:
|
||||
if(!if_generate) generate();
|
||||
return this->sha256_data;
|
||||
}
|
||||
|
||||
private:
|
||||
bool if_generate = false;
|
||||
string raw_data;
|
||||
|
@ -7,7 +7,7 @@
|
||||
using std::string;
|
||||
|
||||
namespace Net {
|
||||
namespace printTools {
|
||||
namespace PrintTools {
|
||||
void printError(const string &error_info) {
|
||||
printf("\033[31mError: %s\033[0m\n", error_info.data());
|
||||
}
|
||||
|
@ -1,3 +1,3 @@
|
||||
add_library(utils STATIC rsa_key_chain.cpp)
|
||||
add_library(utils STATIC rsa_key_chain.cpp aes_cbc_encryptor.cpp random_generator.cpp)
|
||||
|
||||
target_link_libraries(utils debugTools ssl crypto)
|
68
src/utils/aes_cbc_encryptor.cpp
Normal file
68
src/utils/aes_cbc_encryptor.cpp
Normal file
@ -0,0 +1,68 @@
|
||||
//
|
||||
// Created by 胡宇 on 2020/7/7.
|
||||
//
|
||||
|
||||
#include "utils/aes_cbc_encryptor.h"
|
||||
|
||||
|
||||
void Net::AESCBCEncryptor::encrypt(const string &data, string &encrypted_data) {
|
||||
int c_len = data.length() + AES_BLOCK_SIZE, f_len = 0;
|
||||
|
||||
auto *encrypt_buffer = reinterpret_cast<uint8_t *>(malloc(c_len));
|
||||
|
||||
EVP_EncryptInit_ex(e_ctx, nullptr, nullptr, nullptr, nullptr);
|
||||
EVP_EncryptUpdate(e_ctx, encrypt_buffer, &c_len,
|
||||
reinterpret_cast<const unsigned char *>(data.data()), data.length());
|
||||
EVP_EncryptFinal_ex(e_ctx, encrypt_buffer + c_len, &f_len);
|
||||
|
||||
int len = c_len + f_len;
|
||||
|
||||
if(!encrypted_data.empty()) encrypted_data.clear();
|
||||
|
||||
encrypted_data.append(reinterpret_cast<const char *>(encrypt_buffer), len);
|
||||
|
||||
free(encrypt_buffer);
|
||||
}
|
||||
|
||||
void Net::AESCBCEncryptor::decrypt(string &data, const string &encrypt_data) {
|
||||
int p_len = encrypt_data.length(), f_len = 0;
|
||||
auto *plain_buffer = static_cast<uint8_t *>(malloc(p_len));
|
||||
|
||||
EVP_DecryptInit_ex(e_ctx, nullptr, nullptr, nullptr, nullptr);
|
||||
EVP_DecryptUpdate(e_ctx, plain_buffer, &p_len,
|
||||
reinterpret_cast<const unsigned char *>(encrypt_data.data()), encrypt_data.length());
|
||||
EVP_DecryptFinal_ex(e_ctx, plain_buffer + p_len, &f_len);
|
||||
|
||||
int len = p_len + f_len;
|
||||
|
||||
if(!data.empty()) data.clear();
|
||||
|
||||
data.append(reinterpret_cast<const char *>(plain_buffer), len);
|
||||
|
||||
free(plain_buffer);
|
||||
}
|
||||
|
||||
void Net::AESCBCEncryptor::generate_random_key_data() {
|
||||
Rand::UniformUInt rand(0, UINT32_MAX);
|
||||
|
||||
uint32_t p_data[8];
|
||||
for(unsigned int & i : p_data){
|
||||
i = rand.generate();
|
||||
}
|
||||
|
||||
key_data.append(reinterpret_cast<const char *>(p_data), 32);
|
||||
}
|
||||
|
||||
void Net::AESCBCEncryptor::aes_init(string &key_data) {
|
||||
|
||||
|
||||
int i = EVP_BytesToKey(EVP_aes_256_cbc(), EVP_sha256(), nullptr,
|
||||
reinterpret_cast<const unsigned char *>(key_data.c_str()), key_data.length(),
|
||||
nrounds, key, iv);
|
||||
if (i != 32) {
|
||||
throw std::runtime_error("key data must equal 256 bits.");
|
||||
}
|
||||
|
||||
EVP_CIPHER_CTX_init(e_ctx);
|
||||
EVP_EncryptInit_ex(e_ctx, EVP_aes_256_cbc(), nullptr, key, iv);
|
||||
}
|
11
src/utils/random_generator.cpp
Normal file
11
src/utils/random_generator.cpp
Normal file
@ -0,0 +1,11 @@
|
||||
//
|
||||
// Created by 胡宇 on 2020/7/7.
|
||||
//
|
||||
|
||||
#include "utils/random_generator.h"
|
||||
|
||||
boost::random::mt19937 rand_seed;
|
||||
|
||||
int Net::Rand::UniformUInt::generate() const {
|
||||
return uniformInt(rand_seed);
|
||||
}
|
@ -24,13 +24,12 @@ void Net::RSAKeyChain::privateKeyDecrypt(string &data, const string &encrypted_d
|
||||
if(this->key_pair == nullptr) throw runtime_error("key pair is invalid");
|
||||
if(encrypted_data.size() != buffer_size) throw runtime_error("encrypt data's size is abnormal");
|
||||
// 使用私钥解密
|
||||
int decrypted_size = -1;
|
||||
unique_ptr<unsigned char[]>p_buffer (new unsigned char[buffer_size]);
|
||||
if((decrypted_size = RSA_private_decrypt(encrypted_data.size(),
|
||||
if(RSA_private_decrypt(encrypted_data.size(),
|
||||
reinterpret_cast<const unsigned char *>(&encrypted_data[0]),
|
||||
p_buffer.get(),
|
||||
key_pair,
|
||||
RSA_PKCS1_OAEP_PADDING)) == -1)
|
||||
RSA_PKCS1_OAEP_PADDING) == -1)
|
||||
throw runtime_error(ERR_error_string(ERR_get_error(), nullptr));
|
||||
else data = string(reinterpret_cast<const char *>(p_buffer.get()));
|
||||
}
|
||||
@ -46,12 +45,11 @@ void Net::RSAKeyChain::publicKeyEncrypt(const string &data, string &encrypted_da
|
||||
string tmp_data = data;
|
||||
tmp_data.resize(buffer_size - 42);
|
||||
// 使用公钥加密
|
||||
int encrypted_size = -1;
|
||||
if((encrypted_size = RSA_public_encrypt(tmp_data.size(),
|
||||
if(RSA_public_encrypt(tmp_data.size(),
|
||||
reinterpret_cast<const unsigned char *>(&tmp_data[0]),
|
||||
reinterpret_cast<unsigned char *>(&encrypted_data[0]),
|
||||
key_pair,
|
||||
RSA_PKCS1_OAEP_PADDING)) == -1)
|
||||
RSA_PKCS1_OAEP_PADDING) == -1)
|
||||
throw runtime_error(ERR_error_string(ERR_get_error(), nullptr));
|
||||
}
|
||||
|
||||
@ -59,6 +57,6 @@ bool Net::RSAKeyChain::checkKey() {
|
||||
if(!this->if_prv_key) throw runtime_error("illegal call of checkKey");
|
||||
if(this->key_pair == nullptr) throw runtime_error("key pair is invalid");
|
||||
int return_code = RSA_check_key(this->key_pair);
|
||||
if(return_code == -1) throw runtime_error("printTools occur when rsa check key");
|
||||
if(return_code == -1) throw runtime_error("PrintTools occur when rsa check key");
|
||||
else return return_code == 1;
|
||||
}
|
||||
|
25
test/test_util/test_aes.cpp
Normal file
25
test/test_util/test_aes.cpp
Normal file
@ -0,0 +1,25 @@
|
||||
//
|
||||
// Created by 胡宇 on 2020/7/7.
|
||||
//
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "utils/aes_cbc_encryptor.h"
|
||||
|
||||
using namespace Net;
|
||||
|
||||
TEST(AES_Test, base_test_1){
|
||||
AESCBCEncryptor encryptor;
|
||||
|
||||
PrintTools::printInfoBuffer(encryptor.getKeyData(), "Key Data");
|
||||
|
||||
std::string data, encrypt_data;
|
||||
|
||||
encryptor.encrypt("Hello World", encrypt_data);
|
||||
|
||||
PrintTools::printInfoBuffer(encrypt_data, "Encrypt Data");
|
||||
|
||||
encryptor.decrypt(data, encrypt_data);
|
||||
|
||||
ASSERT_EQ(data, std::string("Hello World"));
|
||||
}
|
@ -22,20 +22,20 @@ TEST(RSATest, init_test_1) {
|
||||
TEST(RSATest, generate_test_1) {
|
||||
env->rsa->generateKeyPair();
|
||||
string data = std::to_string(env->rsa->getBufferSize());
|
||||
printTools::printInfo(data, "Buffer Size");
|
||||
PrintTools::printInfo(data, "Buffer Size");
|
||||
}
|
||||
|
||||
TEST(RSATest, pub_encrypt_test_1) {
|
||||
string encrypted_data;
|
||||
env->rsa->publicKeyEncrypt(env->rsa_test_data, encrypted_data);
|
||||
printTools::printInfoBuffer(encrypted_data, "Encrypted Data");
|
||||
PrintTools::printInfoBuffer(encrypted_data, "Encrypted Data");
|
||||
env->rsa_encrypt_data = encrypted_data;
|
||||
}
|
||||
|
||||
TEST(RSATest, prv_decrypt_test_1){
|
||||
string data;
|
||||
env->rsa->privateKeyDecrypt(data, env->rsa_encrypt_data);
|
||||
printTools::printInfo(data, "Decrypt Data");
|
||||
PrintTools::printInfo(data, "Decrypt Data");
|
||||
ASSERT_EQ(data, env->rsa_test_data);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user