2013-12-27 15:05 3699人阅读 评论(1) 收藏 举报
 分类:
Security(38)  C/C++(105) 

版权声明:本文为博主原创文章,未经博主允许不得转载。

将openssl如何生成CSR写了一上DEMO,支持扩展属性,同时增加了通过DN字符串转X509_NAME的方法。

  1. #include <string.h>
  2. #include <openssl/x509.h>
  3. #include <openssl/rsa.h>
  4. #pragma comment(lib, "libeay32.lib")
  5. /*
  6. * subject is expected to be in the format /type0=value0/type1=value1/type2=...
  7. * where characters may be escaped by \
  8. */
  9. X509_NAME *parse_name(char *subject, long chtype, int multirdn)
  10. {
  11. size_t buflen = strlen(subject)+1; /* to copy the types and values into. due to escaping, the copy can only become shorter */
  12. char *buf = OPENSSL_malloc(buflen);
  13. size_t max_ne = buflen / 2 + 1; /* maximum number of name elements */
  14. char **ne_types = OPENSSL_malloc(max_ne * sizeof (char *));
  15. char **ne_values = OPENSSL_malloc(max_ne * sizeof (char *));
  16. int *mval = OPENSSL_malloc (max_ne * sizeof (int));
  17. char *sp = subject, *bp = buf;
  18. int i, ne_num = 0;
  19. X509_NAME *n = NULL;
  20. int nid;
  21. if (!buf || !ne_types || !ne_values || !mval)
  22. {
  23. //BIO_printf(bio_err, "malloc error\n");
  24. goto error;
  25. }
  26. if (*subject != '/')
  27. {
  28. //BIO_printf(bio_err, "Subject does not start with '/'.\n");
  29. goto error;
  30. }
  31. sp++; /* skip leading / */
  32. /* no multivalued RDN by default */
  33. mval[ne_num] = 0;
  34. while (*sp)
  35. {
  36. /* collect type */
  37. ne_types[ne_num] = bp;
  38. while (*sp)
  39. {
  40. if (*sp == '\\') /* is there anything to escape in the type...? */
  41. {
  42. if (*++sp)
  43. *bp++ = *sp++;
  44. else
  45. {
  46. //BIO_printf(bio_err, "escape character at end of string\n");
  47. goto error;
  48. }
  49. }
  50. else if (*sp == '=')
  51. {
  52. sp++;
  53. *bp++ = '\0';
  54. break;
  55. }
  56. else
  57. *bp++ = *sp++;
  58. }
  59. if (!*sp)
  60. {
  61. //BIO_printf(bio_err, "end of string encountered while processing type of subject name element #%d\n", ne_num);
  62. goto error;
  63. }
  64. ne_values[ne_num] = bp;
  65. while (*sp)
  66. {
  67. if (*sp == '\\')
  68. {
  69. if (*++sp)
  70. *bp++ = *sp++;
  71. else
  72. {
  73. //BIO_printf(bio_err, "escape character at end of string\n");
  74. goto error;
  75. }
  76. }
  77. else if (*sp == '/')
  78. {
  79. sp++;
  80. /* no multivalued RDN by default */
  81. mval[ne_num+1] = 0;
  82. break;
  83. }
  84. else if (*sp == '+' && multirdn)
  85. {
  86. /* a not escaped + signals a mutlivalued RDN */
  87. sp++;
  88. mval[ne_num+1] = -1;
  89. break;
  90. }
  91. else
  92. *bp++ = *sp++;
  93. }
  94. *bp++ = '\0';
  95. ne_num++;
  96. }
  97. if (!(n = X509_NAME_new()))
  98. goto error;
  99. for (i = 0; i < ne_num; i++)
  100. {
  101. if ((nid=OBJ_txt2nid(ne_types[i])) == NID_undef)
  102. {
  103. //BIO_printf(bio_err, "Subject Attribute %s has no known NID, skipped\n", ne_types[i]);
  104. continue;
  105. }
  106. if (!*ne_values[i])
  107. {
  108. //BIO_printf(bio_err, "No value provided for Subject Attribute %s, skipped\n", ne_types[i]);
  109. continue;
  110. }
  111. if (!X509_NAME_add_entry_by_NID(n, nid, chtype, (unsigned char*)ne_values[i], -1,-1,mval[i]))
  112. goto error;
  113. }
  114. OPENSSL_free(ne_values);
  115. OPENSSL_free(ne_types);
  116. OPENSSL_free(buf);
  117. OPENSSL_free(mval);
  118. return n;
  119. error:
  120. X509_NAME_free(n);
  121. if (ne_values)
  122. OPENSSL_free(ne_values);
  123. if (ne_types)
  124. OPENSSL_free(ne_types);
  125. if (mval)
  126. OPENSSL_free(mval);
  127. if (buf)
  128. OPENSSL_free(buf);
  129. return NULL;
  130. }
  131. X509_NAME *CreateDN(char *pbEmail, char *pbCN, char *pbOU, char *pbO, char *pbL, char *pbST, char *pbC)
  132. {
  133. X509_NAME *pX509Name = NULL;
  134. if(pbCN == NULL)
  135. {
  136. return NULL;
  137. }
  138. if (!(pX509Name = X509_NAME_new()))
  139. {
  140. return NULL;
  141. }
  142. X509_NAME_add_entry_by_txt(pX509Name, "emailAddress", V_ASN1_UTF8STRING, pbEmail, -1, -1, 0);
  143. X509_NAME_add_entry_by_txt(pX509Name, "CN", V_ASN1_UTF8STRING, pbCN, -1, -1, 0);
  144. X509_NAME_add_entry_by_txt(pX509Name, "OU", V_ASN1_UTF8STRING, pbOU, -1, -1, 0);
  145. X509_NAME_add_entry_by_txt(pX509Name, "O", V_ASN1_UTF8STRING, pbO, -1, -1, 0);
  146. X509_NAME_add_entry_by_txt(pX509Name, "L", V_ASN1_UTF8STRING, pbL, -1, -1, 0);
  147. X509_NAME_add_entry_by_txt(pX509Name, "ST", V_ASN1_UTF8STRING, pbST, -1, -1, 0);
  148. X509_NAME_add_entry_by_txt(pX509Name, "C", V_ASN1_UTF8STRING, pbC, -1, -1, 0);
  149. return pX509Name;
  150. }
  151. int GenCSR(char *pbDN, int nDNLen, char *pCSR, size_t nCSRSize)
  152. {
  153. char szAltName[] = "DNS:www.jinhill.com";
  154. char szComment[] = "Create by Jinhill";
  155. char szKeyUsage[] = "digitalSignature, nonRepudiation";
  156. char szExKeyUsage[] = "serverAuth, clientAuth";
  157. X509_REQ        *pX509Req = NULL;
  158. int             iRV = 0;
  159. long            lVer = 3;
  160. X509_NAME       *pX509DN = NULL;
  161. EVP_PKEY        *pEVPKey = NULL;
  162. RSA             *pRSA = NULL;
  163. X509_NAME_ENTRY *pX509Entry = NULL;
  164. char            szBuf[255] = {0};
  165. char            mdout[20];
  166. int             nLen, nModLen;
  167. int             bits = 2048;
  168. unsigned long   E = RSA_3;
  169. unsigned char   *pDer = NULL;
  170. unsigned char   *p = NULL;
  171. FILE            *fp = NULL;
  172. const EVP_MD    *md = NULL;
  173. X509            *pX509 = NULL;
  174. BIO             *pBIO = NULL;
  175. BIO             *pPemBIO = NULL;
  176. BUF_MEM         *pBMem = NULL;
  177. //STACK_OF(X509_EXTENSION) *pX509Ext;
  178. if(pbDN == NULL)
  179. {
  180. return -1;
  181. }
  182. pX509DN = parse_name(pbDN, V_ASN1_UTF8STRING, 0);
  183. pX509Req = X509_REQ_new();
  184. iRV = X509_REQ_set_version(pX509Req, lVer);
  185. // subject pX509Name
  186. iRV = X509_REQ_set_subject_name(pX509Req, pX509DN);
  187. /* pub key */
  188. pEVPKey = EVP_PKEY_new();
  189. pRSA = RSA_generate_key(bits, E, NULL, NULL);
  190. EVP_PKEY_assign_RSA(pEVPKey, pRSA);
  191. iRV = X509_REQ_set_pubkey(pX509Req, pEVPKey);
  192. /* attribute */
  193. strcpy(szBuf, szAltName);
  194. nLen = strlen(szBuf);
  195. iRV = X509_REQ_add1_attr_by_txt(pX509Req, "subjectAltName", V_ASN1_UTF8STRING, szBuf, nLen);
  196. strcpy(szBuf, szKeyUsage);
  197. nLen = strlen(szBuf);
  198. iRV = X509_REQ_add1_attr_by_txt(pX509Req, "keyUsage", V_ASN1_UTF8STRING, szBuf, nLen);
  199. strcpy(szBuf, szExKeyUsage);
  200. nLen = strlen(szBuf);
  201. iRV = X509_REQ_add1_attr_by_txt(pX509Req, "extendedKeyUsage", V_ASN1_UTF8STRING, szBuf, nLen);
  202. strcpy(szBuf, szComment);
  203. nLen = strlen(szBuf);
  204. iRV = X509_REQ_add1_attr_by_txt(pX509Req, "nsComment", V_ASN1_UTF8STRING, szBuf, nLen);
  205. md = EVP_sha1();
  206. iRV = X509_REQ_digest(pX509Req, md, mdout, &nModLen);
  207. iRV = X509_REQ_sign(pX509Req, pEVPKey, md);
  208. if(!iRV)
  209. {
  210. printf("sign err!\n");
  211. X509_REQ_free(pX509Req);
  212. return -1;
  213. }
  214. // 写入文件PEM格式
  215. //  pBIO = BIO_new_file("certreq.txt", "w");
  216. //  PEM_write_bio_X509_REQ(pBIO, pX509Req, NULL, NULL);
  217. //  BIO_free(pBIO);
  218. //返回PEM字符
  219. pPemBIO = BIO_new(BIO_s_mem());
  220. PEM_write_bio_X509_REQ(pPemBIO, pX509Req, NULL, NULL);
  221. BIO_get_mem_ptr(pPemBIO,&pBMem);
  222. if(pBMem->length <= nCSRSize)
  223. {
  224. memcpy(pCSR, pBMem->data, pBMem->length);
  225. }
  226. BIO_free(pPemBIO);
  227. /* DER编码 */
  228. //nLen = i2d_X509_REQ(pX509Req, NULL);
  229. //pDer = (unsigned char *)malloc(nLen);
  230. //p = pDer;
  231. //nLen = i2d_X509_REQ(pX509Req, &p);
  232. //free(pDer);
  233. //  验证CSR
  234. OpenSSL_add_all_algorithms();
  235. iRV = X509_REQ_verify(pX509Req, pEVPKey);
  236. if(iRV<0)
  237. {
  238. printf("verify err.\n");
  239. }
  240. X509_REQ_free(pX509Req);
  241. return nCSRSize;
  242. }
  243. int main()
  244. {
  245. char chDN[255] = "/CN=www.jinhill.com/O=Beijing Jinhill Inc./C=CN";
  246. char chCSR[2048] = {0};
  247. int rv = GenCSR(chDN, strlen(chDN), chCSR, sizeof(chCSR));
  248. printf("CSR:\n%s", chCSR);
  249. }

openssl 生成CSR的更多相关文章

  1. 使用OpenSSL生成CSR文件,并申请全球通用SSL证书

    http://www.openssl.org 上只有OpenSSL的原代码下载,为了方便Windows用户使用OpenSSL,我们特地为您准备了OpenSSL 0.9.8.a for win32的可执 ...

  2. linux下使用openssl生成 csr crt CA证书

    证书文件生成:一.服务器端1.生成服务器端    私钥(key文件);openssl genrsa -des3 -out server.key 1024运行时会提示输入密码,此密码用于加密key文件( ...

  3. C++ OpenSSL 之三:生成CSR文件

    1.等同于使用: openssl req -new -key "key_path" -out "save_path" -subj "/emailAdd ...

  4. 对称、非对称加密算,openssl生成证书(笔记)

    对称加密算法 1.密钥只有一个,加密和解密都需要同一个密钥2.DES,IDEA,AES3.明文+密钥=密文, 密文+密钥=明文4.加密速度快,系统开销小,适用大量数据的加密 非对称加密算法1.密钥由公 ...

  5. 使用 openssl 生成证书

    一.openssl 简介 目前最流行的 SSL 密码库工具官网:https://www.openssl.org/source/ 构成部分 密码算法库 密钥和证书封装管理功能 SSL通信API接口 用途 ...

  6. openssl生成ssl证书

    openssl生成ssl证书 x509证书一般会用到三类文,key,csr,crt. Key 是私用密钥openssl格,通常是rsa算法. Csr 是证书请求文件,用于申请证书.在制作csr文件的时 ...

  7. CentOS6系统openssl生成证书和自签证书

    CentOS6系统openssl生成证书和自签证书的过程,记录一下,本文基于CentOS 6 64bit.$ yum install openssl openssl-devel 1,生成服务器端的私钥 ...

  8. 用Keytool和OpenSSL生成和签发数字证书

    一)keytool生成私钥文件(.key)和签名请求文件(.csr),openssl签发数字证书      J2SDK在目录%JAVA_HOME%/bin提供了密钥库管理工具Keytool,用于管理密 ...

  9. 使用OpenSSL生成证书

    使用OpenSSL生成证书 下载安装openssl,进入/bin/下面,执行命令(把ssl目录下的openssl.cnf 拷贝到bin目录下)1.首先要生成服务器端的私钥(key文件):openssl ...

随机推荐

  1. FZU 2108(dfs模拟,大数取余)

     K Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status Pr ...

  2. UDK——入门开发流程

    1.入门级參考UnrealScript代码 UnrealScript模仿JAVA,可是又有巨大的不同,主要是它本身具有完好的结构,貌似UDK把一切都安排好了,就像在盖楼一样.面对一幢已经完工的设计静止 ...

  3. java获取当前系统毫秒,纳秒

    //获取当前系统毫秒 System.out.println(System.currentTimeMillis()); //获取当前系统纳秒 System.out.println(System.nano ...

  4. [core java学习笔记][第十章部署应用程序]

    第10章 部署应用程序和applet jar文件 Java Web Start 10.1 jar文件 jar文件就是一个压缩了类,图像和声音的ZIP压缩文件 创建一个新的JAR文件应该使用的常见命令格 ...

  5. linux学习记录 常用指令大全

    1.开启关闭服务器(即时生效): service iptasbles start service iptasbles stop 2.在开启了防火墙时,做如下设置,开启相关端口, 修改/etc/sysc ...

  6. 模板页 相对路径 JS 加载问题

    问题:我在master页面中引入了如下js文件:<script type="text/javascript" src="http://www.cnblogs.com ...

  7. webservice 远程调试配置

    在.NET 中已经默认将WEBSERVICE的远程调试功能关闭,有的时候我们需要远程调试程序的时候,就需要打开此功能我们只需在WEBSERVICE的项目的中添web.config的<system ...

  8. startActivityForResult中回调setResult注意事项

    读 http://www.cnblogs.com/lijunamneg/archive/2013/02/05/2892616.html 有感 文中提出了一个核心问题: Android activity ...

  9. $.getJson()和$.ajax()同步处理

    一.前言 为什么需要用到同步,因为有时候我们给一个提交按钮注册提交表单数据的时候,在提交动作之前会进行一系列的异步ajax请求操作,但是页面js代码会按顺序从上往下面执行,如果你在这过程中进行了异步操 ...

  10. pp to write

    vanishing gradient problem multi-dimensional lstm