#微碼分享#AES演算法的C++包裝類
AES為Advanced Encryption Standard的縮寫,中文名:高階加密標準,在密碼學中又稱Rijndael加密法,是美國聯邦政府採用的一種區塊加密標準,用來替代DES。基於std::string實現的C++包裝類,使用得應用AES演算法十分簡單。完整原始碼連結:
https://github.com/eyjian/libmooon/blob/master/include/mooon/utils/aes_helper.h
https://github.com/eyjian/libmooon/blob/master/src/utils/aes_helper.cpp
aes_helper.h標頭檔案
// 高階加密標準(Advanced Encryption Standard),
// 在密碼學中又稱Rijndael加密法,是美國聯邦政府採用的一種區塊加密標準,用來替代DES
class CAESHelper
{
public:
// 加密資料塊分組長度,必須為128位元(金鑰長度可以是128位元、192位元、256位元中的任意一個)
static int aes_block_size;
public:
// key 金鑰
//
// 因為AES要求key長度只能為128或192或256位元中的一種,即16位元組或24位元組或32位元組中的一種,
// 當key的長度不足16位元組時,CAESHelper自動補0足16位元組,
// 當key的長度間於16位元組和24位元組時,CAESHelper自動補0足24位元組,
// 當key的長度間於24位元組和32位元組時,CAESHelper自動補0足32位元組,
// 當key的長度超出32位元組時,CAESHelper自動擷取前32位元組作為金鑰
CAESHelper(const std::string& key);
~CAESHelper();
void encrypt(const std::string& in, std::string* out);
void decrypt(const std::string& in, std::string* out);
private:
// flag 為true表示加密,為false表示解密
void aes(bool flag, const std::string& in, std::string* out, void* aes_key);
private:
void* _encrypt_key;
void* _decrypt_key;
std::string _key;
};
aes_helper.cpp實現檔案
#if MOOON_HAVE_OPENSSL == 1
int CAESHelper::aes_block_size = AES_BLOCK_SIZE; // 16
#else
int CAESHelper::aes_block_size = 0;
#endif // MOOON_HAVE_OPENSSL
static std::string errcode2errmsg(int errcode)
{
std::string errmsg;
if (0 == errcode)
errmsg = "success";
else if (-1 == errcode)
errmsg = "userkey is empty";
else if (-2 == errcode)
errmsg = "length of userkey is invalid";
else
errmsg = "unknown error";
return errmsg;
}
CAESHelper::CAESHelper(const std::string& key)
{
_encrypt_key = NULL;
_decrypt_key = NULL;
_key = key;
const std::string::size_type LEN16 = 16;
const std::string::size_type LEN24 = 24;
const std::string::size_type LEN32 = 32;
const std::string::size_type len = key.size();
if ((len != LEN16) &&
(len != LEN24) &&
(len != LEN32))
{
if (len < LEN16)
_key.resize(LEN16);
else if (len < LEN24)
_key.resize(LEN24);
else if (len < LEN32)
_key.resize(LEN32);
else
_key.resize(LEN32);
}
}
CAESHelper::~CAESHelper()
{
#if MOOON_HAVE_OPENSSL == 1
delete (AES_KEY*)_encrypt_key;
delete (AES_KEY*)_decrypt_key;
#endif // MOOON_HAVE_OPENSSL
}
void CAESHelper::encrypt(const std::string& in, std::string* out)
{
#if MOOON_HAVE_OPENSSL == 1
if (NULL == _encrypt_key)
{
_encrypt_key = new AES_KEY;
const int errcode = AES_set_encrypt_key((const unsigned char*)(_key.data()), (int)(_key.size()*8), (AES_KEY*)_encrypt_key);
if (errcode != 0) // 理論上不會返回非0,因為建構函式已經處理好了key的長度
{
delete (AES_KEY*)_encrypt_key;
_encrypt_key = NULL;
THROW_EXCEPTION(errcode2errmsg(errcode), errcode);
}
}
aes(true, in, out, _encrypt_key);
#endif // MOOON_HAVE_OPENSSL
}
void CAESHelper::decrypt(const std::string& in, std::string* out)
{
#if MOOON_HAVE_OPENSSL == 1
if (NULL == _decrypt_key)
{
_decrypt_key = new AES_KEY;
const int errcode = AES_set_decrypt_key((const unsigned char*)(_key.data()), (int)(_key.size()*8), (AES_KEY*)_decrypt_key);
if (errcode != 0) // 理論上不會返回非0,因為建構函式已經處理好了key的長度
{
delete (AES_KEY*)_decrypt_key;
_decrypt_key = NULL;
THROW_EXCEPTION(errcode2errmsg(errcode), errcode);
}
}
aes(false, in, out, _decrypt_key);
#endif // MOOON_HAVE_OPENSSL
}
void CAESHelper::aes(bool flag, const std::string& in, std::string* out, void* aes_key)
{
#if MOOON_HAVE_OPENSSL == 1
AES_KEY* aes_key_ = (AES_KEY*)aes_key;
std::string in_tmp = in;
if (in.size() % AES_BLOCK_SIZE != 0)
{
std::string::size_type tmp_size = in.size() + (AES_BLOCK_SIZE - in.size() % AES_BLOCK_SIZE);
in_tmp.resize(tmp_size);
}
const char* in_p = in_tmp.data();
out->resize(in_tmp.size());
char* out_p = const_cast<char*>(out->data());
for (std::string::size_type i=0; i<in.size(); i+=AES_BLOCK_SIZE)
{
char out_tmp[AES_BLOCK_SIZE];
if (flag)
AES_encrypt((const unsigned char*)(in_p), (unsigned char*)(out_tmp), aes_key_);
else
AES_decrypt((const unsigned char*)(in_p), (unsigned char*)(out_tmp), aes_key_);
in_p += AES_BLOCK_SIZE;
memcpy(out_p+i, out_tmp, AES_BLOCK_SIZE);
}
#else
*out = '\0'; // 需要加上這一句,不然難區分HAVE_OPENSSL值是否為1或不為1的情況
#endif // MOOON_HAVE_OPENSSL
}
相關文章
- 包裝類的作用
- 包裝類的使用
- 密碼學之DES/AES演算法密碼學演算法
- 包裝類
- AES 演算法演算法
- Java中的包裝類Java
- Linux 筆記分享十五:原始碼包安裝Linux筆記原始碼
- Linux 筆記分享十六:指令碼安裝包Linux筆記指令碼
- Integer包裝類
- 七,包裝類
- 物件,包裝類物件
- Java 包裝類Java
- 包裝類(Wrapper)APP
- 好程式設計師Java教程分享Java之包裝類與常用類程式設計師Java
- 章13——包裝類——StringBuilder類UI
- 章13——包裝類——Math類
- 包裝類共同點
- 03_包裝類
- AES演算法在Python中的使用演算法Python
- 分組密碼(四)AES演算法① — 密碼學複習(七)演算法密碼學
- AES 加密演算法的詳細介紹加密演算法
- #微碼分享#C++變參字串格式化函式format_stringC++字串格式化函式ORM
- 分享一個的c++寫的,模仿awk的框架類CAwkDocC++框架
- 【Java】基本型別包裝類Java型別
- AES演算法:加密通訊的新選擇演算法加密
- 包裝類到底是幹什麼的
- 14.Java-Arrays(類)、基本型別包裝類、Integer(類)Java型別
- Java實現AES和RSA演算法Java演算法
- 微信支付封裝成npm 包封裝NPM
- Java 包裝類和基本型別Java型別
- java學習筆記(包裝類)Java筆記
- Java中的基本型別包裝類 Integer 類該怎麼使用?Java型別
- Java常用類——包裝類 小白版個人推薦Java
- 作品分享 - 馬雲大大紅包碼的收割機~
- 20.3 OpenSSL 對稱AES加解密演算法解密演算法
- 利用python的KMeans和PCA包實現聚類演算法PythonPCA聚類演算法
- 二十八、基本型別包裝類型別
- 執行緒同步機制-包裝類執行緒