当前位置:   article > 正文

代码示例:OpenSSL AES CBC 加密_openssl aes加密

openssl aes加密

初级代码游戏的专栏介绍与文章目录-CSDN博客

我的github:codetoys,所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。

这些代码大部分以Linux为目标但部分代码是纯C++的,可以在任何平台上使用。


        这是一个基于OpenSSL的AES-CBC加密的例子,其中CBC是自行实现的,原因是OpenSSL的CBC始终有问题,可能是我还没做对吧。这个例程的目的是对配置数据加密,不用于对外交换,所以CBC有没写对我也不能担保——反正这个程序自己加密的自己解密是没问题的。

目录

1 介绍

 2 代码概要

3 主要代码

4 辅助代码

5 openSSL的AES用法

5.1 设置KEY

5.2 加密解密AES_encrypt/AES_decrypt


1 介绍

        这个例程是基于CentOS7/8的,64位,OpenSSL大概是1.1,我也在windows上做了测试,代码可能需要修改,CBC的问题同样存在(所以我就放弃解决了,自己写了一个)。

        使用OpenSSL需要头文件位置和库,如果头文件安装到标准位置则不需要-I参数,库是 -lssl -lcrypt

 2 代码概要

  1. //需要的OpenSSL的两个头文件
  2. #include <openssl/aes.h>
  3. #include <openssl/rand.h>
  4. class CMyOpenSSL
  5. {
  6. private:
  7. //用来输出十六进制数据
  8. static void show_buf(char const* title, unsigned char const* buf, int len)
  9. {
  10. 。。。。。。
  11. }
  12. //需要一个从用户密码生成密钥的函数
  13. //这个函数我没写,有标准算法从密码生成密钥,类似于对密码进行哈希
  14. public:
  15. //这就是一般所说的“盐”
  16. class IV
  17. {
  18. private:
  19. unsigned char iv[AES_BLOCK_SIZE * 5];//其实不需要*5,但我原来就是这么写的,为了调试吧
  20. public:
  21. //执行异或
  22. static void XOR(unsigned char const * iv,unsigned char* data)
  23. {
  24. 。。。。。。
  25. }
  26. //用随机数设置
  27. void Create()
  28. {
  29. 。。。。。。
  30. }
  31. 。。。。。。
  32. };
  33. //由于网上的例子也一样无法解密,所以自行实现CBC
  34. static void my_AES_cbc_encrypt(const unsigned char* in, unsigned char* out, size_t length, const AES_KEY* key, unsigned char* ivec, const int enc)
  35. {
  36. 。。。。。。
  37. }
  38. //AES加密
  39. static int aes_encrypt(unsigned char const* userpasswd, int userpasswd_len, vector<unsigned char> const& in_plain, vector<unsigned char>& out_ciphertext, IV& iv)
  40. {
  41. 。。。。。。
  42. }
  43. //AES解密
  44. static int aes_decrypt(unsigned char const* userpasswd, int userpasswd_len, vector<unsigned char> const& in_ciphertext, vector<unsigned char>& out_plain, IV& iv)
  45. {
  46. 。。。。。。
  47. }
  48. //保护数据,用密码加密并做格式转换
  49. static bool protect_encode(CBuffer const& passwd, CBuffer const& input, CBuffer& output)
  50. {
  51. 。。。。。。
  52. }
  53. //保护数据,用密码加密并做格式转换
  54. static bool protect_decode(CBuffer const& passwd, CBuffer const& input, CBuffer& output)
  55. {
  56. 。。。。。。
  57. }
  58. //下面两个就是网上别人写的程序,一样得不到正确结果
  59. // a simple hex-print routine. could be modified to print 16 bytes-per-line
  60. static void hex_print(const void* pv, size_t len)
  61. {
  62. 。。。。。。
  63. }
  64. // main entrypoint
  65. static int a()
  66. {
  67. 。。。。。。
  68. }
  69. //测试代码
  70. static bool aes_test()
  71. {
  72. 。。。。。。
  73. }
  74. };

        主要函数如下:

my_AES_cbc_encrypt 我自己写的AES-CBC加密和解密,调用了openSSL的AES_encrypt和AES_decrypt,想学习AES怎么用看看这个函数就可以了

aes_encrypt AES加密,调用了openSSL的AES_set_encrypt_key和我自己写的my_AES_cbc_encrypt,为了方便把明文长度作为第一个数据块

 aes_decrypt AES解密,调用了openSSL的AES_set_decrypt_key和我自己写的my_AES_cbc_encrypt

protect_encode和protect_decode是我自己写的加密配置数据的方法,完全是自定义的

a 是网上找来的测试代码,证明AES-CBC确实有问题,不是我一个人的问题

3 主要代码

        下面是主要代码,上面有一些注释是我临时加的,不在完整代码里面,还有一些辅助类后面列出。

  1. #include <openssl/aes.h>
  2. #include <openssl/rand.h>
  3. class CMyOpenSSL
  4. {
  5. private:
  6. static unsigned char const ver;
  7. static void show_buf(char const* title, unsigned char const* buf, int len)
  8. {
  9. cout << title << " ";
  10. for (int i = 0; i < len; ++i)
  11. {
  12. cout << hex << setw(2) << setfill('0') << (unsigned int)buf[i] << " ";
  13. }
  14. cout << endl;
  15. }
  16. //需要一个从用户密码生成密钥的函数
  17. public:
  18. class IV
  19. {
  20. private:
  21. unsigned char iv[AES_BLOCK_SIZE * 5];
  22. public:
  23. IV()
  24. {
  25. memset(iv, 0, AES_BLOCK_SIZE * 5);
  26. }
  27. //执行异或
  28. static void XOR(unsigned char const * iv,unsigned char* data)
  29. {
  30. //show_buf("IV ", iv, AES_BLOCK_SIZE);
  31. //show_buf("DATA", data, AES_BLOCK_SIZE);
  32. for (int i = 0; i < AES_BLOCK_SIZE; ++i)
  33. {
  34. data[i] ^= iv[i];
  35. }
  36. //show_buf("DATA", data, AES_BLOCK_SIZE);
  37. }
  38. int size()const
  39. {
  40. return AES_BLOCK_SIZE;
  41. }
  42. //用随机数设置
  43. void Create()
  44. {
  45. time_t t = time(NULL);
  46. srand(t);
  47. for (int i = 0; i < AES_BLOCK_SIZE; i += sizeof(int))
  48. {
  49. int a = rand();
  50. memcpy(iv + i, &a, sizeof(int));
  51. }
  52. }
  53. void Set(unsigned char const* a)
  54. {
  55. memcpy(iv, a, AES_BLOCK_SIZE);
  56. }
  57. //注意,会修改内容
  58. unsigned char* Get()
  59. {
  60. //show_buf("", iv, AES_BLOCK_SIZE * 2);
  61. return iv;
  62. }
  63. };
  64. //由于网上的例子也一样无法解密,所以自行实现CBC
  65. static void my_AES_cbc_encrypt(const unsigned char* in, unsigned char* out, size_t length, const AES_KEY* key, unsigned char* ivec, const int enc)
  66. {
  67. for (int i = 0; i < length; i += AES_BLOCK_SIZE)
  68. {
  69. if (AES_ENCRYPT == enc)
  70. {
  71. unsigned char tmpin[AES_BLOCK_SIZE];
  72. memcpy(tmpin, in + i, AES_BLOCK_SIZE);
  73. IV::XOR(ivec, tmpin);
  74. AES_encrypt(tmpin, out + i, key);
  75. memcpy(ivec, out + i, AES_BLOCK_SIZE);
  76. }
  77. else
  78. {
  79. unsigned char tmpiv[AES_BLOCK_SIZE];
  80. memcpy(tmpiv, in + i, AES_BLOCK_SIZE);
  81. AES_decrypt(in + i, out + i, key);
  82. IV::XOR(ivec, out + i);
  83. memcpy(ivec, tmpiv, AES_BLOCK_SIZE);
  84. }
  85. }
  86. }
  87. static int aes_encrypt(unsigned char const* userpasswd, int userpasswd_len, vector<unsigned char> const& in_plain, vector<unsigned char>& out_ciphertext, IV& iv)
  88. {
  89. out_ciphertext.clear();
  90. unsigned char userkey[32];//必须是16/24/32
  91. memset((void*)userkey, '\0', 32);
  92. memcpy(userkey, userpasswd, (userpasswd_len > 32 ? 32 : userpasswd_len));
  93. /*设置加密key及密钥长度*/
  94. AES_KEY key;
  95. if (AES_set_encrypt_key(userkey, 32 * 8, &key) < 0)
  96. {
  97. return __LINE__;
  98. }
  99. int len = 0;
  100. /*循环加密,每次只能加密AES_BLOCK_SIZE长度的数据*/
  101. out_ciphertext.reserve(in_plain.size() + AES_BLOCK_SIZE);
  102. while (len < in_plain.size())
  103. {
  104. if (0 == len)
  105. {//第一个块是明文长度
  106. out_ciphertext.resize(out_ciphertext.size() + AES_BLOCK_SIZE);
  107. unsigned char tmp[AES_BLOCK_SIZE];
  108. memset((void*)tmp, '\0', AES_BLOCK_SIZE);
  109. long tmp_len = in_plain.size();
  110. memcpy(tmp, &tmp_len, sizeof(long));
  111. //show_buf("明文长度加密前 ", tmp, AES_BLOCK_SIZE);
  112. my_AES_cbc_encrypt(tmp, &out_ciphertext[out_ciphertext.size() - AES_BLOCK_SIZE], AES_BLOCK_SIZE, &key, iv.Get(), AES_ENCRYPT);
  113. //show_buf("明文长度加密后", &out_ciphertext[out_ciphertext.size() - AES_BLOCK_SIZE], AES_BLOCK_SIZE);
  114. }
  115. out_ciphertext.resize(out_ciphertext.size() + AES_BLOCK_SIZE);
  116. if (in_plain.size() - len < AES_BLOCK_SIZE)
  117. {
  118. unsigned char tmp[AES_BLOCK_SIZE];
  119. memset((void*)tmp, '\0', AES_BLOCK_SIZE);
  120. memcpy(tmp, &in_plain[len], in_plain.size() - len);
  121. my_AES_cbc_encrypt(tmp, &out_ciphertext[out_ciphertext.size() - AES_BLOCK_SIZE], AES_BLOCK_SIZE, &key, iv.Get(), AES_ENCRYPT);
  122. }
  123. else
  124. {
  125. my_AES_cbc_encrypt(&in_plain[len], &out_ciphertext[out_ciphertext.size() - AES_BLOCK_SIZE], AES_BLOCK_SIZE, &key, iv.Get(), AES_ENCRYPT);
  126. }
  127. len += AES_BLOCK_SIZE;
  128. }
  129. return 0;
  130. }
  131. static int aes_decrypt(unsigned char const* userpasswd, int userpasswd_len, vector<unsigned char> const& in_ciphertext, vector<unsigned char>& out_plain, IV& iv)
  132. {
  133. out_plain.clear();
  134. unsigned char userkey[32];//必须是16/24/32
  135. memset((void*)userkey, '\0', 32);
  136. memcpy(userkey, userpasswd, (userpasswd_len > 32 ? 32 : userpasswd_len));
  137. /*设置解密key及密钥长度*/
  138. AES_KEY key;
  139. if (AES_set_decrypt_key(userkey, 32 * 8, &key) < 0)
  140. {
  141. return __LINE__;
  142. }
  143. int len = 0;
  144. /*循环解密*/
  145. out_plain.reserve(in_ciphertext.size());
  146. long out_len = 0;//原始长度,放在第一个加密块
  147. while (len < in_ciphertext.size())
  148. {
  149. if (0 == len)
  150. {//第一个块是明文长度
  151. unsigned char tmp[AES_BLOCK_SIZE];
  152. //show_buf("明文长度解密前", &in_ciphertext[len], AES_BLOCK_SIZE);
  153. my_AES_cbc_encrypt(&in_ciphertext[len], tmp, AES_BLOCK_SIZE, &key, iv.Get(), AES_DECRYPT);
  154. //show_buf("明文长度解密后", tmp, AES_BLOCK_SIZE);
  155. memcpy(&out_len, tmp, sizeof(long));
  156. //thelog << "明文长度应该是 " << out_len << endi;
  157. len += AES_BLOCK_SIZE;
  158. }
  159. out_plain.resize(out_plain.size() + AES_BLOCK_SIZE);
  160. my_AES_cbc_encrypt(&in_ciphertext[len], &out_plain[out_plain.size() - AES_BLOCK_SIZE], AES_BLOCK_SIZE, &key, iv.Get(), AES_DECRYPT);
  161. len += AES_BLOCK_SIZE;
  162. }
  163. //恢复原始长度
  164. if (out_plain.size() > out_len)out_plain.resize(out_len);
  165. return 0;
  166. }
  167. //保护数据,用密码加密并做格式转换
  168. static bool protect_encode(CBuffer const& passwd, CBuffer const& input, CBuffer& output)
  169. {
  170. output.setSize(0);
  171. IV iv;
  172. iv.Create();
  173. CBuffer tmp;
  174. tmp.AddData(&ver, 1);//第一个字节是版本
  175. tmp.AddData(iv.Get(), iv.size());//然后是IV,必须在加密之前保存,加密之后会改变
  176. //加密
  177. vector<unsigned char> in_plain;
  178. in_plain.resize(input.size());
  179. memcpy(&in_plain[0], input.data(), input.size());
  180. vector<unsigned char> out_ciphertext;
  181. aes_encrypt(passwd.data(), passwd.size(), in_plain, out_ciphertext, iv);
  182. thelog << out_ciphertext.size() << endi;
  183. //添加加密后数据
  184. tmp.AddData(&out_ciphertext[0], out_ciphertext.size());
  185. thelog << tmp.size() << endi;
  186. output.reserve(tmp.size() * 4 / 3 + 4 + 1);//三字节转为4字节,编码函数在最后还会加上一个字符串结束符
  187. thelog << output.capacity() << " " << output.size() << endi;
  188. int n = CBase64::Base64Enc(output.lockBuffer(), tmp.data(), tmp.size());
  189. output.releaseBuffer();
  190. if (n > output.capacity())thelog << "长度不足" << ende;
  191. output.setSize(n);
  192. thelog << output.size() << " [" << output.data() << "]" << endi;
  193. return true;
  194. }
  195. //保护数据,用密码加密并做格式转换
  196. static bool protect_decode(CBuffer const& passwd, CBuffer const& input, CBuffer& output)
  197. {
  198. output.setSize(0);
  199. CBuffer tmp;
  200. //这里导致了奇怪的内存错误,实际并不需要这么长
  201. tmp.reserve(input.size() + 100);//实际需要的是4转3,解码函数最后会加上一个字符串结束符
  202. //thelog << input.size() << " " << tmp.capacity() << " " << tmp.size() << endi;
  203. int n = CBase64::Base64Dec(tmp.lockBuffer(), input.data(), input.size());
  204. tmp.releaseBuffer();
  205. if (n<0 || n > tmp.capacity())thelog << "长度不足" << ende;
  206. tmp.setSize(n);
  207. if (tmp.data()[0] != ver)
  208. {
  209. thelog << "加密版本错误" << ende;
  210. return false;
  211. }
  212. else
  213. {
  214. //thelog << "加密版本 " << (int)tmp.data()[0]<<" " << (int)ver << ende;
  215. }
  216. IV iv;
  217. iv.Set(tmp.data() + 1);
  218. vector<unsigned char> in_plain;
  219. in_plain.resize(tmp.size() - 1 - iv.size());
  220. memcpy(&in_plain[0], tmp.data() + 1 + iv.size(), tmp.size() - 1 - iv.size());
  221. //thelog << tmp.size() << " " << in_plain.size() << endi;
  222. vector<unsigned char> out_ciphertext;
  223. aes_decrypt(passwd.data(), passwd.size(), in_plain, out_ciphertext, iv);
  224. output.AddData(&out_ciphertext[0], out_ciphertext.size());
  225. return true;
  226. }
  227. // a simple hex-print routine. could be modified to print 16 bytes-per-line
  228. static void hex_print(const void* pv, size_t len)
  229. {
  230. const unsigned char* p = (const unsigned char*)pv;
  231. if (NULL == pv) {
  232. printf("NULL");
  233. }
  234. else {
  235. size_t i = 0;
  236. for (; i < len; ++i) {
  237. printf("%02X ", *p++);
  238. }
  239. }
  240. printf("\n");
  241. }
  242. // main entrypoint
  243. static int a()
  244. {
  245. int const keylength = 128;
  246. /* generate a key with a given length */
  247. unsigned char aes_key[keylength / 8];
  248. memset(aes_key, 0, keylength / 8);
  249. if (!RAND_bytes(aes_key, keylength / 8)) {
  250. exit(-1);
  251. }
  252. size_t const inputslength = 16;
  253. /* generate input with a given length */
  254. unsigned char aes_input[inputslength];
  255. memset(aes_input, 1, inputslength);
  256. /* init vector */
  257. unsigned char iv_enc[AES_BLOCK_SIZE], iv_dec[AES_BLOCK_SIZE];
  258. RAND_bytes(iv_enc, AES_BLOCK_SIZE);
  259. memcpy(iv_dec, iv_enc, AES_BLOCK_SIZE);
  260. // buffers for encryption and decryption
  261. const size_t encslength = ((inputslength + AES_BLOCK_SIZE) / AES_BLOCK_SIZE) * AES_BLOCK_SIZE;
  262. unsigned char enc_out[encslength];
  263. unsigned char dec_out[inputslength];
  264. memset(enc_out, 0, sizeof(enc_out));
  265. memset(dec_out, 0, sizeof(dec_out));
  266. // so i can do with this aes-cbc-128 aes-cbc-192 aes-cbc-256
  267. AES_KEY enc_key, dec_key;
  268. AES_set_encrypt_key(aes_key, keylength, &enc_key);
  269. AES_cbc_encrypt(aes_input, enc_out, inputslength, &enc_key, iv_enc, AES_ENCRYPT);
  270. AES_set_decrypt_key(aes_key, keylength, &dec_key);
  271. AES_cbc_encrypt(enc_out, dec_out, encslength, &dec_key, iv_dec, AES_DECRYPT);
  272. printf("original:\t");
  273. hex_print(aes_input, sizeof(aes_input));
  274. printf("encrypt:\t");
  275. hex_print(enc_out, sizeof(enc_out));
  276. printf("decrypt:\t");
  277. hex_print(dec_out, sizeof(dec_out));
  278. return 0;
  279. }
  280. static bool aes_test()
  281. {
  282. if (true)
  283. {
  284. unsigned char userkey[32];//必须是16/24/32
  285. memset((void*)userkey, '\0', 32);
  286. memcpy(userkey, "12345", 5);
  287. AES_KEY key;
  288. if (AES_set_encrypt_key(userkey, 16 * 8, &key) < 0)
  289. {
  290. return __LINE__;
  291. }
  292. unsigned char iv[AES_BLOCK_SIZE];
  293. unsigned char data[AES_BLOCK_SIZE];
  294. memset(data, 1, AES_BLOCK_SIZE);
  295. unsigned char data2[AES_BLOCK_SIZE];
  296. memset(data2, 0, AES_BLOCK_SIZE);
  297. unsigned char data3[AES_BLOCK_SIZE * 3];
  298. memset(data3, 0, AES_BLOCK_SIZE * 3);
  299. memset(iv, 0, AES_BLOCK_SIZE);
  300. show_buf("简单输入 ", data, AES_BLOCK_SIZE);
  301. show_buf("iv ", iv, AES_BLOCK_SIZE);
  302. AES_cbc_encrypt(data, data2, AES_BLOCK_SIZE, &key, iv, AES_ENCRYPT);
  303. show_buf("加密后 ", data2, AES_BLOCK_SIZE);
  304. show_buf("iv ", iv, AES_BLOCK_SIZE);
  305. if (AES_set_decrypt_key(userkey, 16 * 8, &key) < 0)
  306. {
  307. return __LINE__;
  308. }
  309. memset(iv, 0, AES_BLOCK_SIZE);
  310. show_buf("解密前 ", data2, AES_BLOCK_SIZE);
  311. show_buf("iv ", iv, AES_BLOCK_SIZE);
  312. AES_cbc_encrypt(data2, data3, AES_BLOCK_SIZE, &key, iv, AES_DECRYPT);
  313. show_buf("简单输出 ", data3, AES_BLOCK_SIZE * 3);
  314. show_buf("iv ", iv, AES_BLOCK_SIZE);
  315. a();
  316. }
  317. if (true)
  318. {
  319. string passwd = "13579";
  320. vector<unsigned char> plaintext;
  321. for (int i = 0; i < 65; ++i)
  322. {
  323. plaintext.push_back(i);
  324. }
  325. vector<unsigned char> out;
  326. IV iv;
  327. iv.Create();
  328. IV iv2;
  329. iv2.Set(iv.Get());
  330. //show_buf("初始IV", iv.Get(), iv.size());
  331. aes_encrypt((unsigned char*)passwd.c_str(), passwd.size(), plaintext, out, iv);
  332. vector<unsigned char> plaintext2;
  333. //show_buf("初始IV", iv2.Get(), iv2.size());
  334. aes_decrypt((unsigned char*)passwd.c_str(), passwd.size(), out, plaintext2, iv2);
  335. thelog << plaintext.size() << " " << out.size() << " " << plaintext2.size() << ENDI;
  336. printf("plantext2: \n");
  337. for (int i = 0; i < plaintext2.size(); i++)
  338. {
  339. printf("%.2x ", plaintext2[i]);
  340. if ((i + 1) % 32 == 0)
  341. {
  342. printf("\n");
  343. }
  344. }
  345. printf("\n");
  346. }
  347. if (true)
  348. {
  349. try
  350. {
  351. char const* plaintext = "1234567890";
  352. CBuffer pass;
  353. CBuffer in;
  354. CBuffer out;
  355. pass.SetData("123");
  356. in.SetData(plaintext);
  357. thelog << in.data() << endi;
  358. protect_encode(pass, in, out);
  359. thelog << out.size() << " [" << out.data() << "]" << endi;
  360. CBuffer out2;
  361. if (!protect_decode(pass, out, out2))thelog << "解码失败" << ende;
  362. thelog << out2.data() << endi;
  363. if (0 == strcmp(plaintext, (char*)out2.data()))
  364. {
  365. thelog << "匹配成功" << endi;
  366. }
  367. else
  368. {
  369. thelog << "匹配失败" << ende;
  370. }
  371. //out2.lockBuffer();
  372. //out2.setSize(10240);
  373. }
  374. catch (...)
  375. {
  376. thelog << "异常发生" << ende;
  377. }
  378. }
  379. return true;
  380. }
  381. };

4 辅助代码

        thelog可以替换为cout,endi、ende可以替换为endl。

        CBuffer就是个包装的缓冲区,代码如下:

  1. //内部隐含保持一个结束符,不计算在容量和大小之内,确保数据可以被当作字符串使用
  2. class CBuffer
  3. {
  4. private:
  5. string name;
  6. unsigned char* p = NULL;
  7. size_t buffer_size = 0;
  8. size_t data_size = 0;
  9. bool bLockBuffer = false;
  10. void _init()
  11. {
  12. static int i = 0;
  13. char buf[64];
  14. sprintf(buf, "CBuffer%d", i++);
  15. name = buf;
  16. if (p)throw "p不为空指针";
  17. p = new unsigned char[1];
  18. if (!p)throw "内存不足";
  19. p[0] = '\0';
  20. buffer_size = 0;
  21. }
  22. public:
  23. CBuffer()
  24. {
  25. _init();
  26. }
  27. CBuffer(CBuffer const & tmp)
  28. {
  29. _init();
  30. SetData(tmp.data(), tmp.data_size);
  31. }
  32. CBuffer & operator=(CBuffer const & tmp)
  33. {
  34. _init();
  35. SetData(tmp.data(), tmp.data_size);
  36. return *this;
  37. }
  38. ~CBuffer()
  39. {
  40. //cout << "~CBuffer " << name <<" "<<(long)p<<" "<< buffer_size<<" "<<data_size << endl;
  41. if (p)delete[]p;
  42. data_size = 0;
  43. buffer_size = 0;
  44. p = NULL;
  45. }
  46. size_t capacity()const { return buffer_size; }
  47. size_t size()const { return data_size; }
  48. unsigned char const * data()const { return p; }
  49. unsigned char* lockBuffer()
  50. {
  51. bLockBuffer = true;
  52. return p;
  53. }
  54. void releaseBuffer() { bLockBuffer = false; }
  55. void setSize(long s)
  56. {
  57. reserve(s);
  58. p[s] = '\0';
  59. data_size = s;
  60. }
  61. bool reserve(size_t n)
  62. {
  63. if (n > buffer_size)
  64. {
  65. if (bLockBuffer)
  66. {
  67. cout << "缓冲区已锁定" << endl;
  68. throw "缓冲区已锁定";
  69. }
  70. //cout << name << " "<< "reserve " << (long)p << " " << buffer_size << " " << data_size << endl;
  71. //cout << name<<"需要扩展 " << buffer_size << " -> " << n << endl;
  72. unsigned char * p2 = new unsigned char[n + 1];
  73. if (p2)
  74. {
  75. if (p)
  76. {
  77. memmove(p2, p, data_size);
  78. delete[]p;
  79. }
  80. buffer_size = n;
  81. p2[data_size] = '\0';
  82. p = p2;
  83. //cout << name<< "扩展成功 " << buffer_size << " -> " << n << endl;
  84. return true;
  85. }
  86. else
  87. {
  88. //cout << name<<"扩展失败 " << buffer_size << " -> " << n << endl;
  89. return false;
  90. }
  91. }
  92. return true;
  93. }
  94. bool AddData(void const * data, long len)
  95. {
  96. if (!reserve(data_size + len))return false;
  97. memmove(p + data_size, data, len);
  98. setSize(data_size + len);
  99. return true;
  100. }
  101. bool SetData(char const * sz)
  102. {
  103. setSize(0);
  104. return AddData((void *)sz, strlen(sz));
  105. }
  106. bool SetData(unsigned char const* sz, long len)
  107. {
  108. return SetData((char const*)sz,len);
  109. }
  110. bool SetData(char const* sz, long len)
  111. {
  112. setSize(0);
  113. return AddData((void *)sz, len);
  114. }
  115. bool Compare(CBuffer const & tmp)const
  116. {
  117. if (data_size != tmp.data_size)return false;
  118. if (data_size > 0)return 0 == memcmp(tmp.data(), data(), data_size);
  119. else return true;
  120. }
  121. };

        CBase64是Base64编码,代码如下:

  1. class CBase64
  2. {
  3. public:
  4. static int Base64Enc(unsigned char *buf, unsigned char const *text,int size)
  5. {
  6. static unsigned char const * base64_encoding = (unsigned char const*)"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  7. int buflen = 0;
  8. while(size>0)
  9. {
  10. *buf++ = base64_encoding[ (text[0] >> 2 ) & 0x3f];
  11. if(size>2)
  12. {
  13. *buf++ = base64_encoding[((text[0] & 3) << 4) | (text[1] >> 4)];
  14. *buf++ = base64_encoding[((text[1] & 0xF) << 2) | (text[2] >> 6)];
  15. *buf++ = base64_encoding[text[2] & 0x3F];
  16. }
  17. else
  18. {
  19. switch(size)
  20. {
  21. case 1:
  22. *buf++ = base64_encoding[(text[0] & 3L) << 4L ];
  23. *buf++ = '=';
  24. *buf++ = '=';
  25. break;
  26. case 2:
  27. *buf++ = base64_encoding[((text[0] & 3) << 4) | (text[1] >> 4)];
  28. *buf++ = base64_encoding[((text[1] & 0x0F) << 2) | (text[2] >> 6)];
  29. *buf++ = '=';
  30. break;
  31. }
  32. }
  33. text +=3;
  34. size -=3;
  35. buflen +=4;
  36. }
  37. *buf = 0;
  38. return buflen;
  39. }
  40. //base64解码的实现
  41. static unsigned char GetBase64Value(unsigned char ch)
  42. {
  43. if ((ch >= 'A') && (ch <= 'Z'))
  44. return ch - 'A';
  45. if ((ch >= 'a') && (ch <= 'z'))
  46. return ch - 'a' + 26;
  47. if ((ch >= '0') && (ch <= '9'))
  48. return ch - '0' + 52;
  49. switch (ch)
  50. {
  51. case '+':
  52. return 62;
  53. case '/':
  54. return 63;
  55. case '=': /* base64 padding */
  56. return 0;
  57. default:
  58. return 0;
  59. }
  60. }
  61. //进行base64解码输入应该是4的倍数(根据mime标准)
  62. //如果不是4倍数返回错误
  63. //注意 如果是最后一个字符 那么长度不准备 可能会多1
  64. //返回buf长度
  65. static int Base64Dec(unsigned char *buf, unsigned char const *text,int size)
  66. {
  67. if(size%4)
  68. return -1;
  69. unsigned char chunk[4];
  70. int parsenum=0;
  71. while(size>0)
  72. {
  73. chunk[0] = GetBase64Value(text[0]);
  74. chunk[1] = GetBase64Value(text[1]);
  75. chunk[2] = GetBase64Value(text[2]);
  76. chunk[3] = GetBase64Value(text[3]);
  77. *buf++ = (chunk[0] << 2) | (chunk[1] >> 4);
  78. *buf++ = (chunk[1] << 4) | (chunk[2] >> 2);
  79. *buf++ = (chunk[2] << 6) | (chunk[3]);
  80. text+=4;
  81. size-=4;
  82. parsenum+=3;
  83. }
  84. buf[parsenum]='\0';
  85. return parsenum;
  86. }
  87. };

5 openSSL的AES用法

5.1 设置KEY

        加密解密的密钥存储为AES_KEY,需要通过AES_set_encrypt_key或AES_set_decrypt_key来设置:

  1. static int aes_encrypt(unsigned char const* userpasswd, int userpasswd_len, vector<unsigned char> const& in_plain, vector<unsigned char>& out_ciphertext, IV& iv)
  2. {
  3. out_ciphertext.clear();
  4. unsigned char userkey[32];//必须是16/24/32
  5. memset((void*)userkey, '\0', 32);
  6. memcpy(userkey, userpasswd, (userpasswd_len > 32 ? 32 : userpasswd_len));
  7. /*设置加密key及密钥长度*/
  8. AES_KEY key;
  9. if (AES_set_encrypt_key(userkey, 32 * 8, &key) < 0)
  10. {
  11. return __LINE__;
  12. }
  13. 。。。。。。

         注意加密和解密的函数是不一样的。

5.2 加密解密AES_encrypt/AES_decrypt

        这两个函数非常简单,参数只有输入、输出、KEY,简单明了。


(这里是文档结束)

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/422737
推荐阅读
  

闽ICP备14008679号