技术文档

Openssl生成csr的解决方案

Openssl 简介

Openssl生成csr的解决方案

构成部分

  • 密码算法库
  • 密钥和证书封装管理功能
  • SSL通信API接口

用途

  1. 建立 RSA、DH、DSA key 参数
  2. 建立509 证书、证书签名请求(CSR)和CRLs(证书回收列表)
  3. 计算消息摘要
  4. 使用各种 Cipher加密/解密
  5. SSL/TLS 客户端以及服务器的测试
  6. 处理S/MIME 或者加密邮件

openssl生成csr的程序方法

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

[cpp]

#include<string.h>

#include<openssl/x509.h>

#include<openssl/rsa.h>

#pragmacomment(lib,“libeay32.lib”)

 

/*

*subjectisexpectedtobeintheformat/type0=value0/type1=value1/type2=…

*wherecharactersmaybeescapedby\

*/

X509_NAME*parse_name(char*subject,longchtype,intmultirdn)

{

size_tbuflen=strlen(subject)+1;/*tocopythetypesandvaluesinto.duetoescaping,thecopycanonlybecomeshorter*/

char*buf=OPENSSL_malloc(buflen);

size_tmax_ne=buflen/2+1;/*maximumnumberofnameelements*/

char**ne_types=OPENSSL_malloc(max_ne*sizeof(char*));

char**ne_values=OPENSSL_malloc(max_ne*sizeof(char*));

int*mval=OPENSSL_malloc(max_ne*sizeof(int));

 

char*sp=subject,*bp=buf;

inti,ne_num=0;

 

X509_NAME*n=NULL;

intnid;

 

if(!buf||!ne_types||!ne_values||!mval)

{

//BIO_printf(bio_err,“mallocerror\n”);

gotoerror;

}

 

if(*subject!=‘/’)

{

//BIO_printf(bio_err,“Subjectdoesnotstartwith‘/’.\n”);

gotoerror;

}

sp++;/*skipleading/*/

 

/*nomultivaluedRDNbydefault*/

mval[ne_num]=0;

 

while(*sp)

{

/*collecttype*/

ne_types[ne_num]=bp;

while(*sp)

{

if(*sp==‘\\’)/*isthereanythingtoescapeinthetype…?*/

{

if(*++sp)

*bp++=*sp++;

else

{

//BIO_printf(bio_err,“escapecharacteratendofstring\n”);

gotoerror;

}

}

elseif(*sp==‘=’)

{

sp++;

*bp++=‘\0’;

break;

}

else

*bp++=*sp++;

}

if(!*sp)

{

//BIO_printf(bio_err,“endofstringencounteredwhileprocessingtypeofsubjectnameelement#%d\n”,ne_num);

gotoerror;

}

ne_values[ne_num]=bp;

while(*sp)

{

if(*sp==‘\\’)

{

if(*++sp)

*bp++=*sp++;

else

{

//BIO_printf(bio_err,“escapecharacteratendofstring\n”);

gotoerror;

}

}

elseif(*sp==‘/’)

{

sp++;

/*nomultivaluedRDNbydefault*/

mval[ne_num+1]=0;

break;

}

elseif(*sp==‘+’&&multirdn)

{

/*anotescaped+signalsamutlivaluedRDN*/

sp++;

mval[ne_num+1]=-1;

break;

}

else

*bp++=*sp++;

}

*bp++=‘\0’;

ne_num++;

}

 

if(!(n=X509_NAME_new()))

gotoerror;

 

for(i=0;i<ne_num;i++)

{

if((nid=OBJ_txt2nid(ne_types[i]))==NID_undef)

{

//BIO_printf(bio_err,“SubjectAttribute%shasnoknownNID,skipped\n”,ne_types[i]);

continue;

}

 

if(!*ne_values[i])

{

//BIO_printf(bio_err,“NovalueprovidedforSubjectAttribute%s,skipped\n”,ne_types[i]);

continue;

}

 

if(!X509_NAME_add_entry_by_NID(n,nid,chtype,(unsignedchar*)ne_values[i],-1,-1,mval[i]))

gotoerror;

}

 

OPENSSL_free(ne_values);

OPENSSL_free(ne_types);

OPENSSL_free(buf);

OPENSSL_free(mval);

returnn;

 

error:

X509_NAME_free(n);

if(ne_values)

OPENSSL_free(ne_values);

if(ne_types)

OPENSSL_free(ne_types);

if(mval)

OPENSSL_free(mval);

if(buf)

OPENSSL_free(buf);

returnNULL;

}

 

X509_NAME*CreateDN(char*pbEmail,char*pbCN,char*pbOU,char*pbO,char*pbL,char*pbST,char*pbC)

{

X509_NAME*pX509Name=NULL;

if(pbCN==NULL)

{

returnNULL;

}

 

if(!(pX509Name=X509_NAME_new()))

{

returnNULL;

}

X509_NAME_add_entry_by_txt(pX509Name,“emailAddress”,V_ASN1_UTF8STRING,pbEmail,-1,-1,0);

X509_NAME_add_entry_by_txt(pX509Name,“CN”,V_ASN1_UTF8STRING,pbCN,-1,-1,0);

X509_NAME_add_entry_by_txt(pX509Name,“OU”,V_ASN1_UTF8STRING,pbOU,-1,-1,0);

X509_NAME_add_entry_by_txt(pX509Name,“O”,V_ASN1_UTF8STRING,pbO,-1,-1,0);

X509_NAME_add_entry_by_txt(pX509Name,“L”,V_ASN1_UTF8STRING,pbL,-1,-1,0);

X509_NAME_add_entry_by_txt(pX509Name,“ST”,V_ASN1_UTF8STRING,pbST,-1,-1,0);

X509_NAME_add_entry_by_txt(pX509Name,“C”,V_ASN1_UTF8STRING,pbC,-1,-1,0);

returnpX509Name;

}

 

intGenCSR(char*pbDN,intnDNLen,char*pCSR,size_tnCSRSize)

{

charszAltName[]=“DNS:www.”;

charszComment[]=“CreatebyJinhill”;

charszKeyUsage[]=“digitalSignature,nonRepudiation”;

charszExKeyUsage[]=“serverAuth,clientAuth”;

 

X509_REQ*pX509Req=NULL;

intiRV=0;

longlVer=3;

X509_NAME*pX509DN=NULL;

EVP_PKEY*pEVPKey=NULL;

RSA*pRSA=NULL;

X509_NAME_ENTRY*pX509Entry=NULL;

charszBuf[255]={0};

charmdout[20];

intnLen,nModLen;

intbits=2048;

unsignedlongE=RSA_3;

unsignedchar*pDer=NULL;

unsignedchar*p=NULL;

FILE*fp=NULL;

constEVP_MD*md=NULL;

X509*pX509=NULL;

BIO*pBIO=NULL;

BIO*pPemBIO=NULL;

BUF_MEM*pBMem=NULL;

 

//STACK_OF(X509_EXTENSION)*pX509Ext;

 

if(pbDN==NULL)

{

return-1;

}

pX509DN=parse_name(pbDN,V_ASN1_UTF8STRING,0);

 

pX509Req=X509_REQ_new();

 

iRV=X509_REQ_set_version(pX509Req,lVer);

 

//subjectpX509Name

iRV=X509_REQ_set_subject_name(pX509Req,pX509DN);

 

/*pubkey*/

pEVPKey=EVP_PKEY_new();

pRSA=RSA_generate_key(bits,E,NULL,NULL);

EVP_PKEY_assign_RSA(pEVPKey,pRSA);

iRV=X509_REQ_set_pubkey(pX509Req,pEVPKey);

 

/*attribute*/

strcpy(szBuf,szAltName);

nLen=strlen(szBuf);

iRV=X509_REQ_add1_attr_by_txt(pX509Req,“subjectAltName”,V_ASN1_UTF8STRING,szBuf,nLen);

 

strcpy(szBuf,szKeyUsage);

nLen=strlen(szBuf);

iRV=X509_REQ_add1_attr_by_txt(pX509Req,“keyUsage”,V_ASN1_UTF8STRING,szBuf,nLen);

 

 

strcpy(szBuf,szExKeyUsage);

nLen=strlen(szBuf);

iRV=X509_REQ_add1_attr_by_txt(pX509Req,“extendedKeyUsage”,V_ASN1_UTF8STRING,szBuf,nLen);

 

 

strcpy(szBuf,szComment);

nLen=strlen(szBuf);

iRV=X509_REQ_add1_attr_by_txt(pX509Req,“nsComment”,V_ASN1_UTF8STRING,szBuf,nLen);

 

 

md=EVP_sha1();

iRV=X509_REQ_digest(pX509Req,md,mdout,&nModLen);

iRV=X509_REQ_sign(pX509Req,pEVPKey,md);

if(!iRV)

{

printf(“signerr!\n”);

X509_REQ_free(pX509Req);

return-1;

}

 

//写入文件PEM格式

//pBIO=BIO_new_file(“certreq.txt”,“w”);

//PEM_write_bio_X509_REQ(pBIO,pX509Req,NULL,NULL);

//BIO_free(pBIO);

 

//返回PEM字符

pPemBIO=BIO_new(BIO_s_mem());

PEM_write_bio_X509_REQ(pPemBIO,pX509Req,NULL,NULL);

BIO_get_mem_ptr(pPemBIO,&pBMem);

if(pBMem->length<=nCSRSize)

{

memcpy(pCSR,pBMem->data,pBMem->length);

}

BIO_free(pPemBIO);

 

/*DER编码*/

//nLen=i2d_X509_REQ(pX509Req,NULL);

//pDer=(unsignedchar*)malloc(nLen);

//p=pDer;

//nLen=i2d_X509_REQ(pX509Req,&p);

//free(pDer);

 

//验证CSR

OpenSSL_add_all_algorithms();

iRV=X509_REQ_verify(pX509Req,pEVPKey);

if(iRV<0)

{

printf(“verifyerr.\n”);

}

 

X509_REQ_free(pX509Req);

returnnCSRSize;

}

 

 

intmain()

{

charchDN[255]=“/CN=www./O=BeijingJinhillInc./C=CN”;

charchCSR[2048]={0};

intrv=GenCSR(chDN,strlen(chDN),chCSR,sizeof(chCSR));

printf(“CSR:\n%s”,chCSR);

}

GDCA()拥有国内自主签发的SSL证书以及是国际知名品牌:GlobalSign、Symantec、GeoTrust SSL证书国内金牌代理商,满足各种用户对SSL的各种要求,广大用户可根据自身的需求向GDCA申请合适的SSL证书,GDCA的专业团队将会为您提供最佳的HTTPS解决方案。

©2020-2024   万云SSL证书  (www.sslssl.com.cn)  万云科技   豫ICP备2020034358号-10