AesCipher.h 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. /************************************************************************/
  2. /* Copyright (C), 2016-2020, [IT], 保留所有权利;
  3. /* 模 块 名:AES算法加解密工具类;
  4. /* 描 述:AES又称Rijndael,是高级加密标准的数据加密解密算法;
  5. /*
  6. /* 版 本:[V];
  7. /* 作 者:[IT];
  8. /* 日 期:[6/3/2016];
  9. /*
  10. /*
  11. /* 注 意:使用宏__AES_IMC_SPEEDUP__能加快生成轮密钥(AesCipher::makeRoundKey),但意味着更多4K内存被使用。
  12. /* 默认情况下,禁用此加速,如果确实使用加速,开启宏定义即可;
  13. /*
  14. /* 修改记录:[IT];
  15. /* 修改日期:;
  16. /* 修改版本:;
  17. /* 修改内容:;
  18. /************************************************************************/
  19. #ifndef __AES_CIPHER_H__
  20. #define __AES_CIPHER_H__
  21. #include <cstring>
  22. #include <climits>
  23. #include <stdexcept>
  24. //#define __AES_IMC_SPEEDUP__ // 加密生成轮密钥的宏;
  25. class AesCipher
  26. {
  27. public:
  28. // AES的工作模式(同样是其他分组(块)加密算法的工作模式)
  29. // ECB:电子密码本模式(Electronic Codebook mode);
  30. // CBC:密码块链接模式(Cipher Block Chaining mode);
  31. // CFB:密码反馈模式(Cipher Feedback mode);
  32. // OFB:输出反馈模式(Output Feedback mode);
  33. // CTR:计数器模式(Counter mode);
  34. enum { ECB = 0, CBC = 1, CFB = 2, OFB = 3, CTR = 4 };
  35. enum { DEFAULT_KEY_LENGTH = 16 }; // 默认密钥长度16字节;
  36. enum { BLOCK_SIZE = 16 }; // 分组(块)大小;
  37. public:
  38. AesCipher() : m_bKey(false), m_bIv(false), m_bCounter(false) { }
  39. // 将用户输入的密钥扩展成轮密钥(轮计算时用到的密钥);
  40. void makeRoundKey(IN const char *key, IN int keyLength = DEFAULT_KEY_LENGTH);
  41. // 为链工作模式(CBC,CFB和OFB)设置初始向量(IV);
  42. void setIV(const char *iv) {
  43. if (iv != 0) {
  44. m_bIv = true;
  45. memcpy(m_iv, iv, BLOCK_SIZE);
  46. } else
  47. m_bIv = false;
  48. }
  49. // 为CTR工作模式设置初始计数器;
  50. // 参数:counter,为CTR(只适应128bits或16Bytes)而设置的初始计数器;
  51. // 注意:低地址字节对应计数器的低位;
  52. void setCounter(const char *counter) {
  53. if (counter != 0) {
  54. m_bCounter = true;
  55. memcpy(m_counter, counter, BLOCK_SIZE);
  56. } else
  57. m_bCounter = false;
  58. }
  59. // 加密多个明文块;
  60. void encrypt(IN const char *in, OUT char *result, IN size_t num, IN int mode = CBC);
  61. // 解密多个密文块;
  62. void decrypt(IN const char *in, OUT char *result, IN size_t num, IN int mode = CBC);
  63. // 用明文长度获取对应的密文长度(返回密文字节数);
  64. static int calculateCipherLen(size_t plaintextlen) {
  65. return (plaintextlen / BLOCK_SIZE + (plaintextlen % BLOCK_SIZE ? 1 : 0) + 1) * 16;
  66. }
  67. // 加密任意长度的明文;
  68. void encryptString(IN const char *in, OUT char *result, IN size_t num, IN int mode = CBC);
  69. // 解密密文;
  70. int decryptString(IN const char *in, OUT char *result, IN size_t num, IN int mode = CBC);
  71. // 获取密钥长度;
  72. int getKeyLength() {
  73. if (!m_bKey)
  74. return 0;
  75. return m_keyLength;
  76. }
  77. // 获取轮次数;
  78. int getRounds() {
  79. if (!m_bKey)
  80. return 0;
  81. return m_rounds;
  82. }
  83. // private types and functions
  84. private:
  85. typedef unsigned __int32 u32_t;
  86. typedef unsigned char u8_t;
  87. // 加密一个块大小的明文,这个块假定是AES的块大小(128bits);
  88. void encryptBlock(IN const char *in, OUT char *result);
  89. // 解密一个块大小的密文,这个块假定是AES的块大小(128bits);
  90. void decryptBlock(IN const char *in, OUT char *result);
  91. // 块的异或(XOR)运行;
  92. static void xorBlock(char *block1, const char *block2) {
  93. for (int i = 0; i < BLOCK_SIZE; ++i)
  94. block1[i] ^= block2[i];
  95. }
  96. // 计数器增加(Increase)1;
  97. bool incrCounter(char *counter);
  98. private:
  99. enum { MAX_ROUNDS = 14 }; // maximum number of round
  100. enum { MAX_KWC = 8 }; // key's maximum number of word
  101. enum { BWC = 4 }; // block's number of word (BLOCK_SIZE / 4)
  102. // Substitute Bytes Transformation Array, S-Box
  103. static const u8_t sm_sbox[256];
  104. // Inverse Substitute Bytes Transformation Array, Inverse S-Box
  105. static const u8_t sm_isbox[256];
  106. // Two-in-one Transform Array: substitute byte & MixColumns transformation
  107. static const u32_t sm_te1[256];
  108. static const u32_t sm_te2[256];
  109. static const u32_t sm_te3[256];
  110. static const u32_t sm_te4[256];
  111. // Two-in-one Transform Array: inverse substitute byte & inverse MixColumns transformation
  112. static const u32_t sm_td1[256];
  113. static const u32_t sm_td2[256];
  114. static const u32_t sm_td3[256];
  115. static const u32_t sm_td4[256];
  116. #ifdef __AES_IMC_SPEEDUP__
  117. // Inverse MixColumns Transformation Array
  118. static const u32_t sm_imc1[256];
  119. static const u32_t sm_imc2[256];
  120. static const u32_t sm_imc3[256];
  121. static const u32_t sm_imc4[256];
  122. #else
  123. // Inverse MixColumns Transformation Function
  124. unsigned char mul(unsigned char a, unsigned char b);
  125. u32_t invMixColumn(u32_t w);
  126. #endif
  127. // Round Constant Array
  128. static const u8_t sm_rcon[52];
  129. bool m_bKey; // key initialization flag
  130. u32_t m_ke[MAX_ROUNDS + 1][BWC]; // encryption round key
  131. u32_t m_kd[MAX_ROUNDS + 1][BWC]; // decryption round key
  132. int m_keyLength; // length of key
  133. int m_rounds; // number of rounds
  134. // initial vector (IV) block, for chain mode
  135. bool m_bIv; // IV initialization flag
  136. char m_iv[BLOCK_SIZE];
  137. // initial counter for CTR mode.
  138. bool m_bCounter; // counter initialization flag
  139. char m_counter[BLOCK_SIZE];
  140. };
  141. #endif //__AES_CIPHER_H__