当前位置:   article > 正文

openssl的使用(c/c++)_openssl 使用 c++ pkcs7

openssl 使用 c++ pkcs7

目录

环境部署

一、openssl RSA加解密、 使用接口生成秘钥

2、使用openssl对文件进行签名认证

3、aes加解密

4、生成证书及证书合法性检查


环境部署

关于openssl的部署比较简单,在之前wifi功能移植中有过说明,或者网上大把详细步骤

一、openssl RSA加解密、 使用接口生成秘钥

命令行的方式生成证书: https://blog.csdn.net/gengxiaoming7/article/details/78505107
参考文章:https://blog.csdn.net/qq_30667875/article/details/105427943

我的具体实现

  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. #include<string.h>
  4. #include<openssl/rsa.h>
  5. #include <openssl/pem.h>
  6. #include <openssl/err.h>
  7. #include <fstream>
  8. using namespace std;
  9. #define LOG_INFO(fmt,args...) ({printf("info: %s(%d) %s:",__FILE__, __LINE__, __func__);printf(fmt"\r\n" ,##args);})
  10. #define LOG_ERROR(fmt,args...) ({printf("error: %s(%d) %s:",__FILE__, __LINE__, __func__);printf(fmt"\r\n" ,##args);})
  11. #define RSA_OPENSSLKEY "./rsa_private_key.pem"
  12. #define RSA_PUBLICKEY "./rsa_public_key.pem"
  13. #define KEY_LENGTH 2048
  14. //生成秘钥
  15. void GenerateRSAKey(std::string & out_pub_key, std::string & out_pri_key);
  16. //传入秘钥内容进行加解密
  17. std::string RsaPriEncrypt(const std::string &clear_text, std::string &pri_key);
  18. std::string RsaPubDecrypt(const std::string & cipher_text, const std::string & pub_key);
  19. //通过读秘钥文件的方式进行加解密
  20. std::string RsaPriEncryptFile(const std::string &clear_text);
  21. std::string RsaPubDecryptFile(const std::string & cipher_text);
  22. int main(int argc, char* argv[])
  23. {
  24. char *p_str="qaq1234567abcdef";
  25. std::string encrypt_text;
  26. std::string decrypt_text;
  27. std::string encryptFile_text;
  28. std::string decryptFile_text;
  29. std::string pub_key;
  30. std::string pri_key;
  31. GenerateRSAKey(pub_key, pri_key);
  32. LOG_INFO("public key:\n");
  33. LOG_INFO("%s\n", pub_key.c_str());
  34. LOG_INFO("private key:\n");
  35. LOG_INFO("%s\n", pri_key.c_str());
  36. // 直接使用秘钥信息的方式加解密
  37. // 私钥加密-公钥解密
  38. encrypt_text = RsaPriEncrypt(p_str, pri_key);
  39. LOG_INFO("encrypt: len=%d\n", encrypt_text.length());
  40. LOG_INFO("decrypt: %s\n", encrypt_text.c_str());
  41. decrypt_text = RsaPubDecrypt(encrypt_text, pub_key);
  42. LOG_INFO("decrypt: len=%d\n", decrypt_text.length());
  43. LOG_INFO("decrypt: %s\n", decrypt_text.c_str());
  44. printf("==================================\n");
  45. // 通过读秘钥文件的方式加解密
  46. encryptFile_text = RsaPriEncryptFile(p_str);
  47. LOG_INFO("encrypt: len=%d\n", encryptFile_text.length());
  48. LOG_INFO("encrypt: %s\n", encryptFile_text.c_str());
  49. decryptFile_text = RsaPubDecryptFile(encryptFile_text);
  50. LOG_INFO("decrypt: len=%d\n", decryptFile_text.length());
  51. LOG_INFO("decrypt: %s\n", decryptFile_text.c_str());
  52. return 0;
  53. }
  54. void GenerateRSAKey(std::string & out_pub_key, std::string & out_pri_key)
  55. {
  56. size_t pri_len = 0; // 私钥长度
  57. size_t pub_len = 0; // 公钥长度
  58. char *pri_key = nullptr; // 私钥
  59. char *pub_key = nullptr; // 公钥
  60. // 生成密钥对
  61. RSA *keypair = RSA_generate_key(KEY_LENGTH, RSA_3, NULL, NULL);
  62. BIO *pri = BIO_new(BIO_s_mem());
  63. BIO *pub = BIO_new(BIO_s_mem());
  64. // 生成私钥
  65. PEM_write_bio_RSAPrivateKey(pri, keypair, NULL, NULL, 0, NULL, NULL);
  66. // 注意------生成第1种格式的公钥
  67. //PEM_write_bio_RSAPublicKey(pub, keypair);
  68. // 注意------生成第2种格式的公钥(此处代码中使用这种)
  69. PEM_write_bio_RSA_PUBKEY(pub, keypair);
  70. // 获取长度
  71. pri_len = BIO_pending(pri);
  72. pub_len = BIO_pending(pub);
  73. // 密钥对读取到字符串
  74. pri_key = (char *)malloc(pri_len + 1);
  75. pub_key = (char *)malloc(pub_len + 1);
  76. BIO_read(pri, pri_key, pri_len);
  77. BIO_read(pub, pub_key, pub_len);
  78. pri_key[pri_len] = '\0';
  79. pub_key[pub_len] = '\0';
  80. out_pub_key = pub_key;
  81. out_pri_key = pri_key;
  82. // 将公钥写入文件
  83. std::ofstream pub_file(RSA_PUBLICKEY, std::ios::out);
  84. if (!pub_file.is_open())
  85. {
  86. perror("pub key file open fail:");
  87. goto ERROR;
  88. return;
  89. }
  90. pub_file << pub_key;
  91. pub_file.close();
  92. // 将私钥写入文件
  93. std::ofstream pri_file(RSA_OPENSSLKEY, std::ios::out);
  94. if (!pri_file.is_open())
  95. {
  96. perror("pri key file open fail:");
  97. goto ERROR;
  98. return;
  99. }
  100. pri_file << pri_key;
  101. pri_file.close();
  102. ERROR:
  103. // 释放内存
  104. RSA_free(keypair);
  105. BIO_free_all(pub);
  106. BIO_free_all(pri);
  107. free(pri_key);
  108. free(pub_key);
  109. }
  110. std::string RsaPriEncrypt(const std::string &clear_text, std::string &pri_key)
  111. {
  112. std::string encrypt_text;
  113. BIO *keybio = BIO_new_mem_buf((unsigned char *)pri_key.c_str(), -1);
  114. RSA* rsa = RSA_new();
  115. rsa = PEM_read_bio_RSAPrivateKey(keybio, &rsa, NULL, NULL);
  116. if (!rsa)
  117. {
  118. BIO_free_all(keybio);
  119. return std::string("");
  120. }
  121. // 获取RSA单次可以处理的数据的最大长度
  122. int len = RSA_size(rsa);
  123. // 申请内存:存贮加密后的密文数据
  124. char *text = new char[len + 1];
  125. memset(text, 0, len + 1);
  126. // 对数据进行私钥加密(返回值是加密后数据的长度)
  127. int ret = RSA_private_encrypt(clear_text.length(), (const unsigned char*)clear_text.c_str(), (unsigned char*)text, rsa, RSA_PKCS1_PADDING);
  128. if (ret >= 0) {
  129. encrypt_text = std::string(text, ret);
  130. }
  131. // 释放内存
  132. delete text;
  133. BIO_free_all(keybio);
  134. RSA_free(rsa);
  135. return encrypt_text;
  136. }
  137. std::string RsaPubDecrypt(const std::string & cipher_text, const std::string & pub_key)
  138. {
  139. std::string decrypt_text;
  140. BIO *keybio = BIO_new_mem_buf((unsigned char *)pub_key.c_str(), -1);
  141. RSA *rsa = RSA_new();
  142. // 注意--------使用第1种格式的公钥进行解密
  143. //rsa = PEM_read_bio_RSAPublicKey(keybio, &rsa, NULL, NULL);
  144. // 注意--------使用第2种格式的公钥进行解密(我们使用这种格式作为示例)
  145. rsa = PEM_read_bio_RSA_PUBKEY(keybio, &rsa, NULL, NULL);
  146. if (!rsa)
  147. {
  148. unsigned long err = ERR_get_error(); //获取错误号
  149. char err_msg[1024] = { 0 };
  150. ERR_error_string(err, err_msg); // 格式:error:errId:库:函数:原因
  151. printf("err msg: err:%ld, msg:%s\n", err, err_msg);
  152. BIO_free_all(keybio);
  153. return decrypt_text;
  154. }
  155. int len = RSA_size(rsa);
  156. char *text = new char[len + 1];
  157. memset(text, 0, len + 1);
  158. // 对密文进行解密
  159. int ret = RSA_public_decrypt(cipher_text.length(), (const unsigned char*)cipher_text.c_str(), (unsigned char*)text, rsa, RSA_PKCS1_PADDING);
  160. if (ret >= 0) {
  161. decrypt_text.append(std::string(text, ret));
  162. }
  163. // 释放内存
  164. delete text;
  165. BIO_free_all(keybio);
  166. RSA_free(rsa);
  167. return decrypt_text;
  168. }
  169. std::string RsaPriEncryptFile(const std::string &clear_text)
  170. {
  171. std::string encrypt_text;
  172. RSA *prikey = RSA_new();
  173. BIO *priio;
  174. priio = BIO_new_file(RSA_OPENSSLKEY, "rb");
  175. prikey = PEM_read_bio_RSAPrivateKey(priio, &prikey, NULL, NULL);
  176. if (!prikey)
  177. {
  178. BIO_free(priio);
  179. return std::string("");
  180. }
  181. int len = RSA_size(prikey);
  182. char *text = new char[len + 1];
  183. memset(text, 0, len + 1);
  184. int ret = RSA_private_encrypt(clear_text.length(), (const unsigned char*)clear_text.c_str(), (unsigned char*)text, prikey, RSA_PKCS1_PADDING);
  185. if (ret >= 0) {
  186. encrypt_text = std::string(text, ret);
  187. }
  188. delete text;
  189. RSA_free(prikey);
  190. BIO_free(priio);
  191. return encrypt_text;
  192. }
  193. std::string RsaPubDecryptFile(const std::string & cipher_text)
  194. {
  195. std::string decrypt_text;
  196. RSA *pubkey = RSA_new();
  197. BIO *pubio;
  198. pubio = BIO_new_file(RSA_PUBLICKEY, "rb");
  199. pubkey = PEM_read_bio_RSA_PUBKEY(pubio, &pubkey, NULL, NULL);
  200. if (!pubkey)
  201. {
  202. unsigned long err = ERR_get_error(); //获取错误号
  203. char err_msg[1024] = { 0 };
  204. ERR_error_string(err, err_msg); // 格式:error:errId:库:函数:原因
  205. printf("err msg: err:%ld, msg:%s\n", err, err_msg);
  206. BIO_free(pubio);
  207. return decrypt_text;
  208. }
  209. int len = RSA_size(pubkey);
  210. char *text = new char[len + 1];
  211. memset(text, 0, len + 1);
  212. int ret = RSA_public_decrypt(cipher_text.length(), (const unsigned char*)cipher_text.c_str(), (unsigned char*)text, pubkey, RSA_PKCS1_PADDING);
  213. if (ret >= 0) {
  214. decrypt_text.append(std::string(text, ret));
  215. }
  216. delete text;
  217. RSA_free(pubkey);
  218. BIO_free(pubio);
  219. return decrypt_text;
  220. }

记得编译时加上 -lssl -lcrypto

2、使用openssl对文件进行签名认证

命令行方式:

message.sign:签名文件

source_ile:目标文件

sha1:摘要算法 使用openssl dgst - 可以看到支持的列表


使用私钥对升级包进行签名
openssl dgst -sha1 -out message.sign -sign rsa_private_key.pem source_file

使用公钥验证签名
openssl dgst -sha1 -verify rsa_public_key.pem -signature message.sign source_file

代码实现

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <sys/stat.h>
  4. #include <openssl/rsa.h>
  5. #include <openssl/pem.h>
  6. #include <openssl/err.h>
  7. #include <openssl/evp.h>
  8. #define SIGN_PATH "./.message.sign" //签名文件
  9. #define SOURCE_PATH "./source_file" //源文件
  10. #define PUBLIC_KEY_PASH "./pub_key.pem" //公钥
  11. static EVP_PKEY *PEM_read_PublicKey(FILE *fp)
  12. {
  13. BIO *b;
  14. EVP_PKEY *ret;
  15. if ((b = BIO_new(BIO_s_file())) == NULL)
  16. {
  17. //PEMerr(PEM_F_PEM_READ_PRIVATEKEY, ERR_R_BUF_LIB);
  18. return(0);
  19. }
  20. BIO_set_fp(b, fp, BIO_NOCLOSE);
  21. ret = PEM_read_bio_PUBKEY(b, NULL, NULL, NULL);
  22. BIO_free(b);
  23. return(ret);
  24. }
  25. static EVP_PKEY* Read_PublicKey(char* p_KeyPath)
  26. {
  27. FILE *fp = NULL;
  28. char szKeyPath[1024];
  29. EVP_PKEY *pubRsa = NULL;
  30. /* 打开密钥文件 */
  31. if (NULL == (fp = fopen(p_KeyPath, "r")))
  32. {
  33. return NULL;
  34. }
  35. /* 获取私密钥 */
  36. pubRsa = PEM_read_PublicKey(fp);
  37. if (NULL == pubRsa)
  38. {
  39. fclose(fp);
  40. return NULL;
  41. }
  42. fclose(fp);
  43. return pubRsa;
  44. }
  45. int VerifyUpgrade(char *sign_data, int sign_len)
  46. {
  47. printf("sign_len = %d\n", sign_len);
  48. int nRet = 0;
  49. EVP_PKEY *pKey;
  50. EVP_MD_CTX* pMdCtx = NULL;
  51. EVP_PKEY_CTX* pKeyCtx = NULL;
  52. /*初始化验签函数*/
  53. pKey = Read_PublicKey(PUBLIC_KEY_PASH);
  54. if (!pKey)
  55. {
  56. printf("Read_PublicKey failed!\n");
  57. return -1;
  58. }
  59. pMdCtx = EVP_MD_CTX_create();
  60. if (NULL == pMdCtx)
  61. {
  62. printf("EVP_MD_CTX_create failed!\n");
  63. EVP_PKEY_free(pKey);
  64. pKey = NULL;
  65. return -1;
  66. }
  67. nRet = EVP_DigestVerifyInit(pMdCtx, &pKeyCtx, EVP_sha256(), NULL, pKey);
  68. if (nRet <= 0)
  69. {
  70. printf("EVP_DigestVerifyInit failed!\n");
  71. EVP_PKEY_free(pKey);
  72. pKey = NULL;
  73. EVP_MD_CTX_destroy(pMdCtx);
  74. pMdCtx = NULL;
  75. return -1;
  76. }
  77. FILE *fp = NULL;
  78. char p_pBuf[512];
  79. fp = fopen(SOURCE_PATH, "r");
  80. while (feof(fp) == 0)
  81. {
  82. int i = fread(p_pBuf, 1, 512, fp);
  83. EVP_DigestVerifyUpdate(pMdCtx, p_pBuf, i);
  84. }
  85. /*验签*/
  86. nRet = EVP_DigestVerifyFinal(pMdCtx, (unsigned char *)sign_data, sign_len);
  87. if (nRet <= 0)
  88. {
  89. printf("EVP_DigestVerifyFinal failed !!! nRet = %d \n", nRet);
  90. EVP_PKEY_free(pKey);
  91. pKey = NULL;
  92. EVP_MD_CTX_destroy(pMdCtx);
  93. pMdCtx = NULL;
  94. fclose(fp);
  95. printf("========================= Verify Failed ========================\n");
  96. return -1;
  97. }
  98. fclose(fp);
  99. printf("========================= Verify Success ========================\n");
  100. return 0;
  101. }
  102. int main()
  103. {
  104. int sign_len = 0;
  105. char *p_sign_data = NULL;
  106. struct stat statbuf;
  107. stat(SIGN_PATH, &statbuf);
  108. sign_len = statbuf.st_size;
  109. p_sign_data = (char *)malloc(sign_len);
  110. memset(p_sign_data, 0, sign_len);
  111. FILE *sign_fp = fopen(SIGN_PATH, "r");
  112. if (sign_fp)
  113. {
  114. fread(p_sign_data, 1, sign_len, sign_fp);
  115. }
  116. VerifyUpgrade(p_sign_data, sign_len);
  117. free(p_sign_data);
  118. return 0;
  119. }

3、aes加解密

命令行方式:

1、ecb

echo -n "AA:BB:CC:11:22:33" | openssl enc -aes-128-ecb -K 78346c3932774542754d32656e345273 | xxd -p -c 64

AA:BB:CC:11:22:33 要加密的字符串

xxd让加密后的内容以十六进制的方式显示,方便查看

2、cbc

echo -n "test" | openssl enc -aes-128-cbc -K 69249e45dd8f1088c6ce8ec74b027035 -iv 69249e45dd8f1088c6ce8ec74b027035 | xxd

代码实现:(这里实现的是cbc,ecb大同小异)

命令行指定的key和iv是十六进制数,为了能跟命令行的输出结果一致,这里简单赋了一下值

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <stdlib.h>
  4. #include <unistd.h>
  5. #include <openssl/evp.h>
  6. #include <openssl/aes.h>
  7. static unsigned char sAesIV[] = "69249e45dd8f1088c6ce8ec74b027035";
  8. static unsigned char sAesKey[] = "69249e45dd8f1088c6ce8ec74b027035";
  9. int AES_ENC(char *_InData, int InLen, char *OutData, int *OutLen)
  10. {
  11. unsigned char key[16] = {}, iv[16] = { 0 };
  12. key[0] = 0x69;
  13. key[1] = 0x24;
  14. key[2] = 0x9e;
  15. key[3] = 0x45;
  16. key[4] = 0xdd;
  17. key[5] = 0x8f;
  18. key[6] = 0x10;
  19. key[7] = 0x88;
  20. key[8] = 0xc6;
  21. key[9] = 0xce;
  22. key[10] = 0x8e;
  23. key[11] = 0xc7;
  24. key[12] = 0x4b;
  25. key[13] = 0x02;
  26. key[14] = 0x70;
  27. key[15] = 0x35;
  28. iv[0] = 0x69;
  29. iv[1] = 0x24;
  30. iv[2] = 0x9e;
  31. iv[3] = 0x45;
  32. iv[4] = 0xdd;
  33. iv[5] = 0x8f;
  34. iv[6] = 0x10;
  35. iv[7] = 0x88;
  36. iv[8] = 0xc6;
  37. iv[9] = 0xce;
  38. iv[10] = 0x8e;
  39. iv[11] = 0xc7;
  40. iv[12] = 0x4b;
  41. iv[13] = 0x02;
  42. iv[14] = 0x70;
  43. iv[15] = 0x35;
  44. EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
  45. EVP_CipherInit_ex(ctx, EVP_aes_128_cbc(), NULL, key, iv, 1);
  46. int len = 0;
  47. EVP_CipherUpdate(ctx, (unsigned char*)OutData, &len, (unsigned char*)_InData, InLen);
  48. *OutLen = len;
  49. EVP_CipherFinal_ex(ctx, (unsigned char*)OutData + len, &len);
  50. *OutLen += len;
  51. EVP_CIPHER_CTX_free(ctx);
  52. return 0;
  53. }
  54. int AES_DEC(char *_InData, int InLen, char *OutData, int *OutLen)
  55. {
  56. unsigned char key[16] = {}, iv[16] = { 0 };
  57. key[0] = 0x69;
  58. key[1] = 0x24;
  59. key[2] = 0x9e;
  60. key[3] = 0x45;
  61. key[4] = 0xdd;
  62. key[5] = 0x8f;
  63. key[6] = 0x10;
  64. key[7] = 0x88;
  65. key[8] = 0xc6;
  66. key[9] = 0xce;
  67. key[10] = 0x8e;
  68. key[11] = 0xc7;
  69. key[12] = 0x4b;
  70. key[13] = 0x02;
  71. key[14] = 0x70;
  72. key[15] = 0x35;
  73. iv[0] = 0x69;
  74. iv[1] = 0x24;
  75. iv[2] = 0x9e;
  76. iv[3] = 0x45;
  77. iv[4] = 0xdd;
  78. iv[5] = 0x8f;
  79. iv[6] = 0x10;
  80. iv[7] = 0x88;
  81. iv[8] = 0xc6;
  82. iv[9] = 0xce;
  83. iv[10] = 0x8e;
  84. iv[11] = 0xc7;
  85. iv[12] = 0x4b;
  86. iv[13] = 0x02;
  87. iv[14] = 0x70;
  88. iv[15] = 0x35;
  89. EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
  90. EVP_CipherInit_ex(ctx, EVP_aes_128_cbc(), NULL, key, iv, 0);
  91. int len = 0;
  92. EVP_CipherUpdate(ctx, (unsigned char*)OutData, &len, (unsigned char*)_InData, InLen);
  93. *OutLen = len;
  94. EVP_CipherFinal_ex(ctx, (unsigned char*)OutData + len, &len);
  95. *OutLen += len;
  96. EVP_CIPHER_CTX_free(ctx);
  97. return 0;
  98. }
  99. int main()
  100. {
  101. char Source[128] = "test";
  102. char EncData[128] = {};
  103. char DecData[128] = {};
  104. int EncLen = 0;
  105. int DecLen = 0;
  106. AES_ENC(Source, (int)strlen(Source), EncData, &EncLen);
  107. for (int i = 0; i < EncLen; ++i)
  108. printf("%02x ", EncData[i]);
  109. printf("\n");
  110. AES_DEC(EncData, (int)strlen(EncData), DecData, &DecLen);
  111. for (int i = 0; i < DecLen; ++i)
  112. printf("%x ", DecData[i]);
  113. printf("\n");
  114. return 0;
  115. }

注意:

openssl默认是PKCS7填充的数据,AES-128AES-192AES-256 的数据块长度分别为 128/8=16bytes192/8=24bytes256/8=32bytes。

当我们拿到一串PKCS7填充的数据时,取其最后一个字符paddingChar,此字符的ASCII码的十进制ord(paddingChar)即为填充的数据长度paddingSize,读取真实数据时去掉填充长度即可得到原始的数据。

命令行输出结果

 代码输出结果

4、生成证书及证书合法性检查

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include "openssl/ssl.h"
  4. #include "openssl/crypto.h"
  5. #include "openssl/conf.h"
  6. #include "openssl/x509v3.h"
  7. #include "openssl/err.h"
  8. #include "openssl/engine.h"
  9. #include "openssl/rsa.h"
  10. //#define BASE64_SIZE(x) (((x)+2) / 3 * 4 + 1)
  11. //#define PADDING_BUF(LEN) (LEN %4 == 0)?(LEN + 4):((LEN + 0x03) &(~0x03))
  12. #define SERVER_CIPHERS "ALL"
  13. #define CLIENT_CIPHERS "ALL:!EXPORT:!LOW"
  14. #define BUF_LEN (128)
  15. #define BUF_BUF (BUF_LEN + 4)
  16. #define CUSTOM_CERT_KEY_PATH "./custom_key.pem"
  17. #define CUSTOM_CERT_REQ_PATH "./certreq.pem"
  18. #define CUSTOM_CERT_TEMP_PATH "./custom_cert_temp.pem"
  19. typedef struct _certificate_params_t
  20. {
  21. char commonName[BUF_BUF];
  22. char country[BUF_BUF];
  23. char stateOrProvince[BUF_BUF];
  24. char locality[BUF_BUF];
  25. char organization[BUF_BUF];
  26. char organizationUnit[BUF_BUF];
  27. }certificate_params_t;
  28. //创建证书请求文件pem
  29. static int create_cret(certificate_params_t *param);
  30. static int check_certs_availability(const char *p_ciphers, const char *p_ca, const char *p_cert,const char *p_private_key);
  31. int main(int argc, char *argv[])
  32. {
  33. certificate_params_t param = {};
  34. memcpy(param.country,"SZ" , BUF_LEN);
  35. memcpy(param.stateOrProvince,"GD", BUF_LEN);
  36. memcpy(param.locality,"NS", BUF_LEN);
  37. memcpy(param.organization,"MYSELF", BUF_LEN);
  38. memcpy(param.organizationUnit,"MY" , BUF_LEN);
  39. memcpy(param.commonName,"SS", BUF_LEN);
  40. create_cret(&param);
  41. return 0;
  42. //TODO
  43. //write file
  44. //检查证书是否合法
  45. check_certs_availability(SERVER_CIPHERS, NULL, CUSTOM_CERT_TEMP_PATH, CUSTOM_CERT_KEY_PATH);//check证书有误
  46. return 0;
  47. }
  48. static int _name_entry_create_by_txt(X509_NAME* name,X509_NAME_ENTRY *entry,const char *field,const char* pNameStr,int nameLen)
  49. {
  50. if(0==nameLen || nameLen> 128 || NULL==name || NULL==pNameStr)
  51. return -1;
  52. char bytes[128]={0};
  53. memset(&bytes,0,sizeof(bytes));
  54. memcpy(bytes, pNameStr,sizeof(bytes) );
  55. int len = strlen(bytes);
  56. entry = X509_NAME_ENTRY_create_by_txt(&entry, field, V_ASN1_UTF8STRING, (unsigned char*)bytes, len);
  57. X509_NAME_add_entry(name, entry, 0, -1);
  58. return 0;
  59. }
  60. static int create_cret(certificate_params_t *param)
  61. {
  62. if(NULL == param)
  63. return -1;
  64. X509_NAME_ENTRY* entry = NULL;
  65. const EVP_MD* md;
  66. BIO* b;
  67. unsigned long e = RSA_3;
  68. char mdout[20];
  69. int mdlen;
  70. int bits = 1024;//512;
  71. int ret = 0;
  72. X509_REQ*req = X509_REQ_new();
  73. long version = 1;
  74. ret = X509_REQ_set_version(req, version);
  75. X509_NAME* name = X509_NAME_new();
  76. //Common Name (e.g. server FQDN or YOUR name) CN
  77. if( 0!=_name_entry_create_by_txt( name, entry, "commonName", param->commonName, BUF_LEN) )
  78. {
  79. printf(" [%s %d] _name_entry_create_by_txt commonName err!!! \n",__FUNCTION__,__LINE__);
  80. return -2;
  81. }
  82. //Country Name (2 letter code) C
  83. if( 0!=_name_entry_create_by_txt( name, entry, "countryName", param->country, BUF_LEN) )
  84. {
  85. printf(" [%s %d] _name_entry_create_by_txt countryName err!!! \n",__FUNCTION__,__LINE__);
  86. return -3;
  87. }
  88. //State or Province Name (full name) ST
  89. if( 0!=_name_entry_create_by_txt( name, entry, "stateOrProvinceName", param->stateOrProvince, BUF_LEN) )
  90. {
  91. printf(" [%s %d] _name_entry_create_by_txt stateOrProvinceName err!!! \n",__FUNCTION__,__LINE__);
  92. return -4;
  93. }
  94. //Locality Name (eg, city) L
  95. if( 0!=_name_entry_create_by_txt( name, entry, "localityName", param->locality, BUF_LEN) )
  96. {
  97. printf(" [%s %d] _name_entry_create_by_txt localityName err!!! \n",__FUNCTION__,__LINE__);
  98. return -5;
  99. }
  100. //Organization Name (eg, company) O
  101. if( 0!=_name_entry_create_by_txt( name, entry, "organizationName", param->organization, BUF_LEN) )
  102. {
  103. printf(" [%s %d] _name_entry_create_by_txt organizationName err!!! \n",__FUNCTION__,__LINE__);
  104. return -6;
  105. }
  106. //Organizational Unit Name (eg, section) OU
  107. if( 0!=_name_entry_create_by_txt( name, entry, "organizationalUnitName", param->organizationUnit, BUF_LEN) )
  108. {
  109. printf(" [%s %d] _name_entry_create_by_txt organizationalUnitName err!!! \n",__FUNCTION__,__LINE__);
  110. return -7;
  111. }
  112. /* subject name */
  113. //申请者信息
  114. ret = X509_REQ_set_subject_name(req, name);
  115. /* pub key */
  116. EVP_PKEY*pkey = EVP_PKEY_new();
  117. RSA*rsa = RSA_generate_key(bits, e, NULL, NULL);
  118. EVP_PKEY_assign_RSA(pkey, rsa);
  119. ret = X509_REQ_set_pubkey(req, pkey);
  120. /* 写入私钥PEM格式 */
  121. b = BIO_new_file(CUSTOM_CERT_KEY_PATH, "w");
  122. if(!PEM_write_bio_RSAPrivateKey( b, rsa, NULL,NULL, 0,0, NULL) )//往BIO中写入一个私钥,采用3DES加密
  123. printf("PEM_write_bio_RSAPrivateKey err!\n");
  124. BIO_free(b);
  125. /* 写入公钥PEM格式 */
  126. /*
  127. b = BIO_new_file("certpubkey.pem", "w");
  128. if (!PEM_write_bio_RSAPublicKey(b, rsa))
  129. printf("PEM_write_bio_RSAPublicKey err!\n");
  130. BIO_free(b);
  131. */
  132. md = EVP_sha1();
  133. ret = X509_REQ_digest(req, md, (unsigned char *)mdout, (unsigned int *)&mdlen);// 根据指定的摘要算法,对X509_REQ结构做摘要计算
  134. ret = X509_REQ_sign(req, pkey, md);
  135. if (!ret)
  136. {
  137. printf("sign err!\n");
  138. X509_REQ_free(req);
  139. return -8;
  140. }
  141. /* 写入文件PEM格式 */
  142. b = BIO_new_file(CUSTOM_CERT_REQ_PATH, "w");
  143. PEM_write_bio_X509_REQ(b, req );
  144. BIO_free(b);
  145. X509_REQ_free(req);
  146. return 0;
  147. }
  148. static int check_certs_availability(const char *p_ciphers, const char *p_ca, const char *p_cert,const char *p_private_key)
  149. {
  150. SSL_library_init();//必须加上不然有概率出现SSL_CTX_new返回NULL
  151. SSL_CTX *p_ssl_ctx = SSL_CTX_new((SSL_METHOD*)SSLv23_method());
  152. if (!p_ssl_ctx)
  153. {
  154. printf("Create SSL CTX fail!\n");
  155. SSL_CTX_free(p_ssl_ctx);
  156. p_ssl_ctx = NULL;
  157. return -1;
  158. }
  159. printf("new ssl ctx ok\n");
  160. //SSL_CTX_set_options((SSL_CTX*)p_ssl_ctx, SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1);
  161. SSL_CTX_set_options(p_ssl_ctx, SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3|SSL_OP_NO_TLSv1);
  162. SSL_CTX_set_mode(p_ssl_ctx, SSL_MODE_AUTO_RETRY |
  163. SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
  164. SSL_MODE_ENABLE_PARTIAL_WRITE |
  165. SSL_MODE_RELEASE_BUFFERS);
  166. /* 指定加密套件 */
  167. if (p_ciphers)//SERVER_CIPHERS
  168. {
  169. if (SSL_CTX_set_cipher_list(p_ssl_ctx, p_ciphers) != 1)
  170. {
  171. printf("Set cipher fail!\n");
  172. ERR_print_errors_fp(stderr);
  173. SSL_CTX_free(p_ssl_ctx);
  174. return -1;
  175. }
  176. printf("set cipher ok\n");
  177. }
  178. SSL_CTX_set_verify(p_ssl_ctx, SSL_VERIFY_NONE, NULL);//?
  179. /* 加载受信任的证书列表 */
  180. if (p_ca)
  181. {
  182. if (SSL_CTX_load_verify_locations(p_ssl_ctx, p_ca, NULL) == 0)
  183. {
  184. printf("Load trust CA [%s] fail!\n",p_ca);
  185. ERR_print_errors_fp(stderr);
  186. SSL_CTX_free(p_ssl_ctx);
  187. return -1;
  188. }
  189. printf("load [%s] ca ok\n",p_ca);
  190. }
  191. if ( NULL!=p_cert && !SSL_CTX_use_certificate_file(p_ssl_ctx, p_cert, X509_FILETYPE_PEM))
  192. {
  193. SSL_CTX_free(p_ssl_ctx);
  194. p_ssl_ctx = NULL;
  195. printf("Load cert [%s] fail!\n",p_cert);
  196. return -1;
  197. }
  198. printf("load cert [%s] ok\n",p_cert);
  199. if (NULL!=p_private_key && !SSL_CTX_use_PrivateKey_file(p_ssl_ctx, p_private_key, X509_FILETYPE_PEM))
  200. {
  201. SSL_CTX_free(p_ssl_ctx);
  202. p_ssl_ctx = NULL;
  203. printf("Load private key [%s] fail!\n",p_private_key);
  204. return -1;
  205. }
  206. printf("use private key [%s] ok\n",p_private_key);
  207. if (!SSL_CTX_check_private_key(p_ssl_ctx))
  208. {
  209. SSL_CTX_free(p_ssl_ctx);
  210. p_ssl_ctx = NULL;
  211. printf("Check private key fail!\n");
  212. return -1;
  213. }
  214. printf("@@@@@@@@@@ [ltz] check cert and private ok!!! \n");
  215. SSL_CTX_set_quiet_shutdown(p_ssl_ctx, 1);
  216. SSL_CTX_free(p_ssl_ctx);
  217. return 0;
  218. }

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

闽ICP备14008679号