当前位置:   article > 正文

C++使用openssl对数据进行加解密_openssl加密 c++

openssl加密 c++

1. openssl库文件及头文件的获取
获取openssl库文件及头文件有两种方式:

1)下载OpenSSL源代码并由自己编译后使用

2)下载已编译好的安装包,安装后直接可以得到openssl的库文件及头文件

使用第一种方法获取,过程十分繁琐,同时编译过程中可能产生各种各种的问题,因此这里使用第二种方法获取openssl库文件及头文件。

下载安装包(https://slproweb.com/products/Win32OpenSSL.html),并进行安装,安装后安装目录如下图,其中bin文件夹内的为动态库文件、lib文件夹内的为静态库文件、include文件夹内的为头文件

2. 使用openssl对数据进行加解密
1) 新建工程,引入openssl头文件及库文件

2) 示例代码如下,示例代码包含了:

a. 摘要(散列)算法md5、sha256;

b. 对称加密算法des;

c. 非对称加密算法rsa。
 

  1. #include <iostream>
  2. #include <cassert>
  3. #include <string>
  4. #include <vector>
  5. #include "openssl/md5.h"
  6. #include "openssl/sha.h"
  7. #include "openssl/des.h"
  8. #include "openssl/rsa.h"
  9. #include "openssl/pem.h"
  10. #pragma comment(lib,"libcrypto.lib")
  11. // ---- md5摘要哈希 ---- //
  12. void md5(const std::string &srcStr, std::string &encodedStr, std::string &encodedHexStr)
  13. {
  14. unsigned char mdStr[33] = { 0 };
  15. MD5((const unsigned char *)srcStr.c_str(), srcStr.length(), mdStr);// 调用md5哈希
  16. encodedStr = std::string((const char *)mdStr);// 哈希后的字符串
  17. char buf[65] = { 0 };
  18. char tmp[3] = { 0 };
  19. for (int i = 0; i < 32; i++)// 哈希后的十六进制串 32字节
  20. {
  21. sprintf(tmp, "%02x", mdStr[i]);
  22. strcat(buf, tmp);
  23. }
  24. buf[32] = '\0'; // 后面都是0,从32字节截断
  25. encodedHexStr = std::string(buf);
  26. }
  27. // ---- sha256摘要哈希 ---- //
  28. void sha256(const std::string &srcStr, std::string &encodedStr, std::string &encodedHexStr)
  29. {
  30. unsigned char mdStr[33] = { 0 };
  31. SHA256((const unsigned char *)srcStr.c_str(), srcStr.length(), mdStr);// 调用sha256哈希
  32. encodedStr = std::string((const char *)mdStr);// 哈希后的字符串
  33. char buf[65] = { 0 };
  34. char tmp[3] = { 0 };
  35. for (int i = 0; i < 32; i++)// 哈希后的十六进制串 32字节
  36. {
  37. sprintf(tmp, "%02x", mdStr[i]);
  38. strcat(buf, tmp);
  39. }
  40. buf[32] = '\0'; // 后面都是0,从32字节截断
  41. encodedHexStr = std::string(buf);
  42. }
  43. // ---- des对称加解密 ---- //
  44. // 加密 ecb模式
  45. std::string des_encrypt(const std::string &clearText, const std::string &key)
  46. {
  47. std::string cipherText; // 密文
  48. DES_cblock keyEncrypt;
  49. memset(keyEncrypt, 0, 8);
  50. // 构造补齐后的密钥
  51. if (key.length() <= 8)
  52. memcpy(keyEncrypt, key.c_str(), key.length());
  53. else
  54. memcpy(keyEncrypt, key.c_str(), 8);
  55. // 密钥置换
  56. DES_key_schedule keySchedule;
  57. DES_set_key_unchecked(&keyEncrypt, &keySchedule);
  58. // 循环加密,每8字节一次
  59. const_DES_cblock inputText;
  60. DES_cblock outputText;
  61. std::vector<unsigned char> vecCiphertext;
  62. unsigned char tmp[8];
  63. for (int i = 0; i < clearText.length() / 8; i++)
  64. {
  65. memcpy(inputText, clearText.c_str() + i * 8, 8);
  66. DES_ecb_encrypt(&inputText, &outputText, &keySchedule, DES_ENCRYPT);
  67. memcpy(tmp, outputText, 8);
  68. for (int j = 0; j < 8; j++)
  69. vecCiphertext.push_back(tmp[j]);
  70. }
  71. if (clearText.length() % 8 != 0)
  72. {
  73. int tmp1 = clearText.length() / 8 * 8;
  74. int tmp2 = clearText.length() - tmp1;
  75. memset(inputText, 0, 8);
  76. memcpy(inputText, clearText.c_str() + tmp1, tmp2);
  77. DES_ecb_encrypt(&inputText, &outputText, &keySchedule, DES_ENCRYPT);// 加密函数
  78. memcpy(tmp, outputText, 8);
  79. for (int j = 0; j < 8; j++)
  80. vecCiphertext.push_back(tmp[j]);
  81. }
  82. cipherText.clear();
  83. cipherText.assign(vecCiphertext.begin(), vecCiphertext.end());
  84. return cipherText;
  85. }
  86. // 解密 ecb模式
  87. std::string des_decrypt(const std::string &cipherText, const std::string &key)
  88. {
  89. std::string clearText; // 明文
  90. DES_cblock keyEncrypt;
  91. memset(keyEncrypt, 0, 8);
  92. if (key.length() <= 8)
  93. memcpy(keyEncrypt, key.c_str(), key.length());
  94. else
  95. memcpy(keyEncrypt, key.c_str(), 8);
  96. DES_key_schedule keySchedule;
  97. DES_set_key_unchecked(&keyEncrypt, &keySchedule);
  98. const_DES_cblock inputText;
  99. DES_cblock outputText;
  100. std::vector<unsigned char> vecCleartext;
  101. unsigned char tmp[8];
  102. for (int i = 0; i < cipherText.length() / 8; i++)
  103. {
  104. memcpy(inputText, cipherText.c_str() + i * 8, 8);
  105. DES_ecb_encrypt(&inputText, &outputText, &keySchedule, DES_DECRYPT);
  106. memcpy(tmp, outputText, 8);
  107. for (int j = 0; j < 8; j++)
  108. vecCleartext.push_back(tmp[j]);
  109. }
  110. if (cipherText.length() % 8 != 0)
  111. {
  112. int tmp1 = cipherText.length() / 8 * 8;
  113. int tmp2 = cipherText.length() - tmp1;
  114. memset(inputText, 0, 8);
  115. memcpy(inputText, cipherText.c_str() + tmp1, tmp2);
  116. DES_ecb_encrypt(&inputText, &outputText, &keySchedule, DES_DECRYPT);// 解密函数
  117. memcpy(tmp, outputText, 8);
  118. for (int j = 0; j < 8; j++)
  119. vecCleartext.push_back(tmp[j]);
  120. }
  121. clearText.clear();
  122. clearText.assign(vecCleartext.begin(), vecCleartext.end());
  123. return clearText;
  124. }
  125. // ---- rsa非对称加解密 ---- //
  126. #define KEY_LENGTH 2048 // 密钥长度
  127. #define PUB_KEY_FILE "pubkey.pem" // 公钥路径
  128. #define PRI_KEY_FILE "prikey.pem" // 私钥路径
  129. // 函数方法生成密钥对
  130. void generateRSAKey(std::string strKey[2])
  131. {
  132. // 公私密钥对
  133. size_t pri_len;
  134. size_t pub_len;
  135. char *pri_key = NULL;
  136. char *pub_key = NULL;
  137. // 生成密钥对
  138. RSA *keypair = RSA_generate_key(KEY_LENGTH, RSA_3, NULL, NULL);
  139. BIO *pri = BIO_new(BIO_s_mem());
  140. BIO *pub = BIO_new(BIO_s_mem());
  141. PEM_write_bio_RSAPrivateKey(pri, keypair, NULL, NULL, 0, NULL, NULL);
  142. PEM_write_bio_RSAPublicKey(pub, keypair);
  143. // 获取长度
  144. pri_len = BIO_pending(pri);
  145. pub_len = BIO_pending(pub);
  146. // 密钥对读取到字符串
  147. pri_key = (char *)malloc(pri_len + 1);
  148. pub_key = (char *)malloc(pub_len + 1);
  149. BIO_read(pri, pri_key, pri_len);
  150. BIO_read(pub, pub_key, pub_len);
  151. pri_key[pri_len] = '\0';
  152. pub_key[pub_len] = '\0';
  153. // 存储密钥对
  154. strKey[0] = pub_key;
  155. strKey[1] = pri_key;
  156. // 存储到磁盘(这种方式存储的是begin rsa public key/ begin rsa private key开头的)
  157. FILE *pubFile = fopen(PUB_KEY_FILE, "w");
  158. if (pubFile == NULL)
  159. {
  160. assert(false);
  161. return;
  162. }
  163. fputs(pub_key, pubFile);
  164. fclose(pubFile);
  165. FILE *priFile = fopen(PRI_KEY_FILE, "w");
  166. if (priFile == NULL)
  167. {
  168. assert(false);
  169. return;
  170. }
  171. fputs(pri_key, priFile);
  172. fclose(priFile);
  173. // 内存释放
  174. RSA_free(keypair);
  175. BIO_free_all(pub);
  176. BIO_free_all(pri);
  177. free(pri_key);
  178. free(pub_key);
  179. }
  180. // 命令行方法生成公私钥对(begin public key/ begin private key
  181. // 找到openssl命令行工具,运行以下
  182. // openssl genrsa -out prikey.pem 1024
  183. // openssl rsa - in privkey.pem - pubout - out pubkey.pem
  184. // 公钥加密
  185. std::string rsa_pub_encrypt(const std::string &clearText, const std::string &pubKey)
  186. {
  187. std::string strRet;
  188. RSA *rsa = NULL;
  189. BIO *keybio = BIO_new_mem_buf((unsigned char *)pubKey.c_str(), -1);
  190. // 此处有三种方法
  191. // 1, 读取内存里生成的密钥对,再从内存生成rsa
  192. // 2, 读取磁盘里生成的密钥对文本文件,在从内存生成rsa
  193. // 3,直接从读取文件指针生成rsa
  194. RSA* pRSAPublicKey = RSA_new();
  195. rsa = PEM_read_bio_RSAPublicKey(keybio, &rsa, NULL, NULL);
  196. int len = RSA_size(rsa);
  197. char *encryptedText = (char *)malloc(len + 1);
  198. memset(encryptedText, 0, len + 1);
  199. // 加密函数
  200. int ret = RSA_public_encrypt(clearText.length(), (const unsigned char*)clearText.c_str(), (unsigned char*)encryptedText, rsa, RSA_PKCS1_PADDING);
  201. if (ret >= 0)
  202. strRet = std::string(encryptedText, ret);
  203. // 释放内存
  204. free(encryptedText);
  205. BIO_free_all(keybio);
  206. RSA_free(rsa);
  207. return strRet;
  208. }
  209. // 私钥解密
  210. std::string rsa_pri_decrypt(const std::string &cipherText, const std::string &priKey)
  211. {
  212. std::string strRet;
  213. RSA *rsa = RSA_new();
  214. BIO *keybio;
  215. keybio = BIO_new_mem_buf((unsigned char *)priKey.c_str(), -1);
  216. // 此处有三种方法
  217. // 1, 读取内存里生成的密钥对,再从内存生成rsa
  218. // 2, 读取磁盘里生成的密钥对文本文件,在从内存生成rsa
  219. // 3,直接从读取文件指针生成rsa
  220. rsa = PEM_read_bio_RSAPrivateKey(keybio, &rsa, NULL, NULL);
  221. int len = RSA_size(rsa);
  222. char *decryptedText = (char *)malloc(len + 1);
  223. memset(decryptedText, 0, len + 1);
  224. // 解密函数
  225. int ret = RSA_private_decrypt(cipherText.length(), (const unsigned char*)cipherText.c_str(), (unsigned char*)decryptedText, rsa, RSA_PKCS1_PADDING);
  226. if (ret >= 0)
  227. strRet = std::string(decryptedText, ret);
  228. // 释放内存
  229. free(decryptedText);
  230. BIO_free_all(keybio);
  231. RSA_free(rsa);
  232. return strRet;
  233. }
  234. int main(int argc, char **argv)
  235. {
  236. // 原始明文
  237. std::string srcText = "this is an example";
  238. std::string encryptText;
  239. std::string encryptHexText;
  240. std::string decryptText;
  241. std::cout << "=== 原始明文 ===" << std::endl;
  242. std::cout << srcText << std::endl;
  243. // md5
  244. std::cout << "=== md5哈希 ===" << std::endl;
  245. md5(srcText, encryptText, encryptHexText);
  246. std::cout << "摘要字符: " << encryptText << std::endl;
  247. std::cout << "摘要串: " << encryptHexText << std::endl;
  248. // sha256
  249. std::cout << "=== sha256哈希 ===" << std::endl;
  250. sha256(srcText, encryptText, encryptHexText);
  251. std::cout << "摘要字符: " << encryptText << std::endl;
  252. std::cout << "摘要串: " << encryptHexText << std::endl;
  253. // des
  254. std::cout << "=== des加解密 ===" << std::endl;
  255. std::string desKey = "12345";
  256. encryptText = des_encrypt(srcText, desKey);
  257. std::cout << "加密字符: " << std::endl;
  258. std::cout << encryptText << std::endl;
  259. decryptText = des_decrypt(encryptText, desKey);
  260. std::cout << "解密字符: " << std::endl;
  261. std::cout << decryptText << std::endl;
  262. // rsa
  263. std::cout << "=== rsa加解密 ===" << std::endl;
  264. std::string key[2];
  265. generateRSAKey(key);
  266. std::cout << "公钥: " << std::endl;
  267. std::cout << key[0] << std::endl;
  268. std::cout << "私钥: " << std::endl;
  269. std::cout << key[1] << std::endl;
  270. encryptText = rsa_pub_encrypt(srcText, key[0]);
  271. std::cout << "加密字符: " << std::endl;
  272. std::cout << encryptText << std::endl;
  273. decryptText = rsa_pri_decrypt(encryptText, key[1]);
  274. std::cout << "解密字符: " << std::endl;
  275. std::cout << decryptText << std::endl;
  276. system("pause");
  277. return 0;
  278. }

 

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

闽ICP备14008679号