⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 openssl.txt

📁 web中安装证书 在web页面上生成证书请求 调用CreatePKCS10接口 调用openssl接口生成请求
💻 TXT
字号:
标题:程序中生成证书请求的两种方法

时间:2004-07-30  
来源:中国信息安全组织[原创] 

程序中生成证书请求的两种方法

Rainbow(不经历风雨,怎么见彩虹)

/********************************************************************************************************************
声明:本文档用于学习与研究可以自由转载,无论以何种形式发布都必须保留完整的版权声明,商业用途不得转载.本人能力有限,如有问题欢迎交流与指正。
网站:http://www.infosecurity.org.cn
论坛:http://www.infosecurity.org.cn/forum/forum.html
邮件:rainbow_zrh@sina.com webmaster@infosecurity.org.cn
*********************************************************************************************************************/
一、在web页面上生成证书请求
在本地生成的证书请求的方式适用于CA不备份私钥或者说该私钥用于签名的情况。
1、枚举CSP
生成私钥的时候是通过枚举本地的CSP进行的,这个功能只需要通过调用xenroll.dll的
enumProviders接口来实现。举例如下:


EnumProviders function EnumProviders()
 nCSPIndex=0 
 ON ERROR resume next
 do 
   sProviderName=IControl.enumProviders(nCSPIndex, 0) 
   if err.Number<>0 then
     If &H80070103=Err.Number Then 
       Err.Clear
       exit do
     elseif err.number = 438 then
       document.location="xenroll.dll"
       exit do
     else
       msgbox Err.description
       exit do
     end if 
   end if
  /*在这里添加你自己对CSP的显示部分*/
 loop
end function 


2、另外几个接口
xenroll.dll ---与生成证书请求相关的另外几接口是
KeySpec     ---用于设置或取得密钥的类型(即签名AT_SIGNATURE或密钥交换AT_KEYEXCHANGE)
HashAlgorithm-- 用于设置或取得对证书进行散列的算法,可以为MD2/MD5/SHA1,默认是SHA1.
GenKeyFlags---- 用于控制生成的私钥是否可以导出。默认是不可导出的,但可以设置成CRYPT_EXPORTABLE
或者按<wincrypt.h>里的定义#define CRYPT_EXPORTABLE 0x00000001直接设置成1也可以。
ProviderName-- 就是CSP的名字,就是从注册表时读的名字。
3、生成DN
自己可以做一个简单的网页用来接收输入信息,我们将用这些信息生成dn.如果有对DN不熟悉的可以看一下
网站里pki/pmi版面的内容。
比如:我们可以用vbscript定义一个dn的变量,然后将它们拼接起来。


DN = "";
DN = DN + "C=" + "\"" + cCountry + "\"" + ",";
DN = DN + "S=" + "\"" + cState + "\"" + ",";
DN = DN + "L=" + "\"" + cCity + "\"" + ",";
DN = DN + "CN=" + "\"" + cName + "\"" + ",";
DN = DN + "E=" + "\"" + cEMail + "\""; 


4、调用CreatePKCS10接口
这个接口有两个参数第一个是上面所说的DN,另外一个是证书的用途,这里就一长串的OID,具体的用途
可以看一下x.509 v3的rfx文档,也可以到网站的<<安全标准栏目>>去下载。
举例如下:
szPKCS10 = IControl.CreatePKCS10(DN, "1.3.6.1.5.5.7.3.2");

二、调用openssl接口生成请求

调用OpenSSL接口生成证书相对复杂一点,不过也可通过下面几个步骤来完成。
1、生成RSA密钥对
第一个参数是密钥的长度,第二个是RSA算法中的e,这个参数在pkcs#1中有建议,
这里取65535(细节请到安全标准栏目中下载相关文档)
示例代码如下:


EVP_PKEY *pkey = NULL;
RSA *rsa = NULL;
rsa = RSA_generate_key(*(pReq->keylen),0x10001,NULL,NULL);
pkey = EVP_PKEY_new();
if(!EVP_PKEY_assign_RSA(pkey,rsa))
{
m_str.Format("%s","generate RSA key pair error");
goto err;
} 


2、生成X509Name
在这里我用了一个类来处理


// 加一个条目
int CX509Name::AddEntry(int key, char *value)
{

char *key_value[]={"countryName","stateOrProvinceName","localityName",
"organizationName","organizationalUnitName","commonName",
"emailAddress"};
int nid;
X509_NAME_ENTRY *ent;
if(subject == NULL)return -1;
if ((nid = OBJ_txt2nid(key_value[key])) == NID_undef)
return -1;
if (!(ent = X509_NAME_ENTRY_create_by_NID(NULL, nid,
MBSTRING_ASC,(unsigned char*)value, -1)))
return -1;
if (X509_NAME_add_entry(subject, ent, -1, 0) != 1)
return -1;
return 1;
}
// 取得最终的结果
X509_NAME* CX509Name::getName(REQ_INFO *p)
{
if(p->szCN) AddEntry(0,p->szCN);
if(p->szST) AddEntry(0,p->szST);
if(p->szL) AddEntry(0,p->szL);
if(p->szO) AddEntry(0,p->szO);
if(p->szOU) AddEntry(0,p->szOU);
if(p->szName) AddEntry(0,p->szName);
if(p->szEmail) AddEntry(0,p->szEmail);
return subject;
} 


3、设置好其它信息并签名
除了上面所的信息要设置以外,还要设置版本号、公钥、名字等。


req=X509_REQ_new();
if(!req)
{
goto err;
} 
subject=x_name.getName(pReq);
if(!subject)
{
goto err;
}
if(!X509_REQ_set_version(req,0L)) goto err;
if(!X509_REQ_set_subject_name(req,subject)) goto err;
if(!X509_REQ_set_pubkey(req,pkey)) goto err;
if(!X509_REQ_sign(req,pkey,digest)) goto err; 


4、保存


// output private key
outPvk = BIO_new_file(szPrivateKeyFileName, "w");
if (!outPvk) 
{
  m_str.Format("Error opening file %s", szPrivateKeyFileName);
  goto err;
}
if (pkey)
{
  if(szPrivateKeyPwd)
  {
    int len =strlen(szPrivateKeyPwd);
    PEM_write_bio_PrivateKey(outPvk, pkey, EVP_des_ede3_cbc(), 
     (unsigned char*)szPrivateKeyPwd,len, NULL, NULL);
  }
  else
   PEM_write_bio_PrivateKey(outPvk, pkey, NULL,NULL,0, NULL, NULL);
}
// output certificate request file
outReq = BIO_new_file(szReqFileName, "w");
if (!outReq) 
{
   m_str.Format("Error opening file %s", szReqFileName);
   goto err;
}
if (req)
{
   PEM_write_bio_X509_REQ(outReq, req);
} 



以上代码中是片段,仅供参考,本人能力有限,欢迎交流与指正,谢谢。
如果还有不清楚的地方,欢迎到论坛提问

 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -