Chinaunix首页 | 论坛 | 博客
  • 博客访问: 6424785
  • 博文数量: 567
  • 博客积分: 13065
  • 博客等级: 上将
  • 技术积分: 10046
  • 用 户 组: 普通用户
  • 注册时间: 2008-03-26 16:44
个人简介

推荐: blog.csdn.net/aquester https://github.com/eyjian https://www.cnblogs.com/aquester http://blog.chinaunix.net/uid/20682147.html

文章分类

全部博文(567)

分类: C/C++

2019-01-24 14:36:09

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头文件
  1. // 高级加密标准(Advanced Encryption Standard),
  2. // 在密码学中又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准,用来替代DES
  3. class CAESHelper
  4. {
  5. public:
  6.     // 加密数据块分组长度,必须为128比特(密钥长度可以是128比特、192比特、256比特中的任意一个)
  7.     static int aes_block_size;

  8. public:
  9.     // key 密钥
  10.     //
  11.     // 因为AES要求key长度只能为128或192或256比特中的一种,即16字节或24字节或32字节中的一种,
  12.     // 当key的长度不足16字节时,CAESHelper自动补0足16字节,
  13.     // 当key的长度间于16字节和24字节时,CAESHelper自动补0足24字节,
  14.     // 当key的长度间于24字节和32字节时,CAESHelper自动补0足32字节,
  15.     // 当key的长度超出32字节时,CAESHelper自动截取前32字节作为密钥
  16.     CAESHelper(const std::string& key);
  17.     ~CAESHelper();

  18.     void encrypt(const std::string& in, std::string* out);
  19.     void decrypt(const std::string& in, std::string* out);

  20. private:
  21.     // flag 为true表示加密,为false表示解密
  22.     void aes(bool flag, const std::string& in, std::string* out, void* aes_key);

  23. private:
  24.     void* _encrypt_key;
  25.     void* _decrypt_key;
  26.     std::string _key;
  27. };
aes_helper.cpp文件
  1. #if MOOON_HAVE_OPENSSL == 1
  2. int CAESHelper::aes_block_size = AES_BLOCK_SIZE; // 16
  3. #else
  4. int CAESHelper::aes_block_size = 0;
  5. #endif // MOOON_HAVE_OPENSSL

  6. static std::string errcode2errmsg(int errcode)
  7. {
  8.     std::string errmsg;

  9.     if (0 == errcode)
  10.         errmsg = "success";
  11.     else if (-1 == errcode)
  12.         errmsg = "userkey is empty";
  13.     else if (-2 == errcode)
  14.         errmsg = "length of userkey is invalid";
  15.     else
  16.         errmsg = "unknown error";
  17.     return errmsg;
  18. }

  19. CAESHelper::CAESHelper(const std::string& key)
  20. {
  21.     _encrypt_key = NULL;
  22.     _decrypt_key = NULL;
  23.     _key = key;

  24.     const std::string::size_type LEN16 = 16;
  25.     const std::string::size_type LEN24 = 24;
  26.     const std::string::size_type LEN32 = 32;
  27.     const std::string::size_type len = key.size();
  28.     if ((len != LEN16) &&
  29.         (len != LEN24) &&
  30.         (len != LEN32))
  31.     {
  32.         if (len < LEN16)
  33.             _key.resize(LEN16);
  34.         else if (len < LEN24)
  35.             _key.resize(LEN24);
  36.         else if (len < LEN32)
  37.             _key.resize(LEN32);
  38.         else
  39.             _key.resize(LEN32);
  40.     }
  41. }

  42. CAESHelper::~CAESHelper()
  43. {
  44. #if MOOON_HAVE_OPENSSL == 1
  45.     delete (AES_KEY*)_encrypt_key;
  46.     delete (AES_KEY*)_decrypt_key;
  47. #endif // MOOON_HAVE_OPENSSL
  48. }

  49. void CAESHelper::encrypt(const std::string& in, std::string* out)
  50. {
  51. #if MOOON_HAVE_OPENSSL == 1
  52.     if (NULL == _encrypt_key)
  53.     {
  54.         _encrypt_key = new AES_KEY;

  55.         const int errcode = AES_set_encrypt_key((const unsigned char*)(_key.data()), (int)(_key.size()*8), (AES_KEY*)_encrypt_key);
  56.         if (errcode != 0) // 理论上不会返回非0,因为构造函数已经处理好了key的长度
  57.         {
  58.             delete (AES_KEY*)_encrypt_key;
  59.             _encrypt_key = NULL;
  60.             THROW_EXCEPTION(errcode2errmsg(errcode), errcode);
  61.         }
  62.     }

  63.     aes(true, in, out, _encrypt_key);
  64. #endif // MOOON_HAVE_OPENSSL
  65. }

  66. void CAESHelper::decrypt(const std::string& in, std::string* out)
  67. {
  68. #if MOOON_HAVE_OPENSSL == 1
  69.     if (NULL == _decrypt_key)
  70.     {
  71.         _decrypt_key = new AES_KEY;

  72.         const int errcode = AES_set_decrypt_key((const unsigned char*)(_key.data()), (int)(_key.size()*8), (AES_KEY*)_decrypt_key);
  73.         if (errcode != 0) // 理论上不会返回非0,因为构造函数已经处理好了key的长度
  74.         {
  75.             delete (AES_KEY*)_decrypt_key;
  76.             _decrypt_key = NULL;
  77.             THROW_EXCEPTION(errcode2errmsg(errcode), errcode);
  78.         }
  79.     }

  80.     aes(false, in, out, _decrypt_key);
  81. #endif // MOOON_HAVE_OPENSSL
  82. }

  83. void CAESHelper::aes(bool flag, const std::string& in, std::string* out, void* aes_key)
  84. {
  85. #if MOOON_HAVE_OPENSSL == 1
  86.     AES_KEY* aes_key_ = (AES_KEY*)aes_key;

  87.     std::string in_tmp = in;
  88.     if (in.size() % AES_BLOCK_SIZE != 0)
  89.     {
  90.         std::string::size_type tmp_size = in.size() + (AES_BLOCK_SIZE - in.size() % AES_BLOCK_SIZE);
  91.         in_tmp.resize(tmp_size);
  92.     }

  93.     const char* in_p = in_tmp.data();
  94.     out->resize(in_tmp.size());
  95.     char* out_p = const_cast<char*>(out->data());

  96.     for (std::string::size_type i=0; i<in.size(); i+=AES_BLOCK_SIZE)
  97.     {
  98.         char out_tmp[AES_BLOCK_SIZE];

  99.         if (flag)
  100.             AES_encrypt((const unsigned char*)(in_p), (unsigned char*)(out_tmp), aes_key_);
  101.         else
  102.             AES_decrypt((const unsigned char*)(in_p), (unsigned char*)(out_tmp), aes_key_);

  103.         in_p += AES_BLOCK_SIZE;
  104.         memcpy(out_p+i, out_tmp, AES_BLOCK_SIZE);
  105.     }
  106. #else
  107.     *out = '\0'; // 需要加上这一句,不然难区分HAVE_OPENSSL值是否为1或不为1的情况
  108. #endif // MOOON_HAVE_OPENSSL
  109. }




阅读(47174) | 评论(2) | 转发(0) |
给主人留下些什么吧!~~

mmz_772019-02-20 15:24:17

好的很好的

评论热议
请登录后评论。

登录 注册