// ca_demo.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

#include <openssl/conf.h>
#include <openssl/bio.h>
#include <openssl/err.h>
#include <openssl/bn.h>
#include <openssl/txt_db.h>
#include <openssl/evp.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>
#include <openssl/objects.h>
#include <openssl/pem.h>
#include <openssl/engine.h>
#include <openssl/pkcs12.h>
#include <memory.h>
#include <malloc.h>
#include <stdio.h>

/**//*描述符长度*/
#define MA_X509_ENTITY_LEN 128

/**//*密钥对文件名字长度*/
#define MA_X509_RSAKEY_FILENAME_LEN 256

/**//*证书文件名字长度*/
#define MA_X509_CERT_FILENAME_LEN 256

/**//*密钥对长度*/
#define MA_X509_RSAKEY_LEN 1024

/**//*版本号*/
#define MA_X509_V1 0
#define MA_X509_V2 1
#define MA_X509_V3 2

/**//*序列号*/
#define MA_SN 1111

/**//*设置RSA密钥对的存储密钥*/
char *szX509RsaPswd = "PASSWORD";

X509_REQ *req = NULL;
X509_NAME *pSubjectName=NULL;
X509_NAME_ENTRY *ent=NULL;
EVP_PKEY *pNewRsaKey = NULL;
EVP_MD *digest=NULL;

/**//*CONFIG*/
char szCountry[MA_X509_ENTITY_LEN] = ...{0};
char szState[MA_X509_ENTITY_LEN] = ...{0};
char szLocation[MA_X509_ENTITY_LEN] = ...{0};
char szCommonName[MA_X509_ENTITY_LEN] = ...{0};
char szOrganization[MA_X509_ENTITY_LEN] = ...{0};
char szOrganizationUnit[MA_X509_ENTITY_LEN] = ...{0};
char szIsser[MA_X509_ENTITY_LEN] = ...{0};
unsigned long ulSn = 0;

char szRsaKeyFileName[MA_X509_RSAKEY_FILENAME_LEN] = ...{0};
char szRsaKey[MA_X509_RSAKEY_LEN] = ...{0};
char szCertFileName[MA_X509_CERT_FILENAME_LEN] = ...{0};
char szCaRsaKeyFileName[MA_X509_RSAKEY_FILENAME_LEN] = ...{0};

/**//*CA证书*/
X509 *m_pCACert = NULL;

int isCa = 0;

/**//*默认配置*/
int read_init()
...{
FILE *pFile = NULL;

strcpy(szCountry, "CN");
strcpy(szState, "ZJ");
strcpy(szLocation, "HZ");
strcpy(szCommonName, "CA_TEST");
strcpy(szOrganization, "CODESTART");
strcpy(szOrganizationUnit, "FW");

pFile = fopen("config.ini", "r");
if(NULL == pFile)
...{
printf("read_init:read config file error ");
return -1;
}

/**//******************
CN=piky
COUNTRY=CN
STATE=ZJ
LOCATION=HZ
ORGANIZATION=SNS
ISSUER=SELF
******************/

fscanf(pFile, "CN=%s ", szCommonName);
fscanf(pFile, "COUNTRY=%s ", szCountry);
fscanf(pFile, "STATE=%s ", szState);
fscanf(pFile, "LOCATION=%s ", szLocation);
fscanf(pFile, "ORGANIZATION=%s ", szOrganization);
fscanf(pFile, "ISSUER=%s ", szIsser);
fscanf(pFile, "ISSUERKEY=%s ", szCaRsaKeyFileName);
fscanf(pFile, "SN=%d", &ulSn);

printf("read entity: CN=%s,COUNTRY=%s,STATE=%s,LOCATION=%s,ORGANIZATION=%s,ISSUER=%s,ISSUERKEY=%s ",
szCommonName,
szCountry,
szState,
szLocation,
szOrganization,
szIsser,
szCaRsaKeyFileName);

sprintf(szCertFileName, "CN=%s.cert.pem", szCommonName);
sprintf(szRsaKeyFileName, "CN=%s.key.pem",szCommonName);

if (!strcmp(szIsser, "SELF") || 0 == szIsser[0])
...{
isCa = 1;
sprintf(szCertFileName, "ca.cert.pem");
sprintf(szRsaKeyFileName, "ca.key.pem");
}

return 0;
}

int read_cert(X509** pCert, char *pCertFile)
...{
BIO *pbio;
if(NULL == pCert || NULL == pCertFile)
...{
printf("read_cert:parament error(%x,%x) ", *pCert, pCertFile);
return -1;
}

pbio = BIO_new_file(pCertFile,"r");
if(NULL == pbio)
...{
printf("read_cert:create bio file error ");
return -1;
}

*pCert = PEM_read_bio_X509(pbio,NULL,NULL,NULL);
if(NULL == *pCert)
...{
printf("read_cert:call PEM_read_bio_X509 error ");
BIO_free(pbio);
return -1;
}

BIO_free(pbio);
return 0;
}

int read_rsa_key(EVP_PKEY **pNewRsaKey, char *pRsaKeyFile, unsigned char*pPwd)
...{
BIO *pbio;
if(NULL == pNewRsaKey || NULL == pRsaKeyFile || NULL == pPwd)
...{
return -1;
}

pbio = BIO_new_file(pRsaKeyFile,"r");
if(NULL == pbio)
...{
return -1;
}

*pNewRsaKey = PEM_read_bio_PrivateKey(pbio,NULL,0,NULL);
if(NULL == *pNewRsaKey)
...{
printf("read_rsa_key:call PEM_read_bio_PrivateKey error ");
BIO_free(pbio);
return -1;
}

BIO_free(pbio);
return 0;
}

/**//*存储RSA密钥对*/
int save_rsa_key(EVP_PKEY *pNewRsaKey)
...{
BIO *pbio;

if(NULL == pNewRsaKey)
...{
return -1;
}

pbio = BIO_new_file(szRsaKeyFileName,"w");
if(NULL == pbio)
...{
printf(" save_rsa_key:create bio file error");
return -1;
}

/**//*存储密钥*/
/**//*if(!PEM_write_bio_PrivateKey(pbio, pNewRsaKey,EVP_des_cbc(),
(unsigned char *)szX509RsaPswd, strlen(szX509RsaPswd),0,NULL))*/

if(!PEM_write_bio_PrivateKey(pbio, pNewRsaKey,NULL,NULL, 0,0,NULL))
...{
printf("save_rsa_key:call PEM_write_bio_PrivateKey error");
return -1;
}

BIO_free(pbio);
return 0;
}

/**//*存储证书*/
int save_cert(X509 *pCert, char *pCertFile)
...{
BIO *pbio;

if(NULL == pCert || NULL == pCertFile)
...{
return -1;
}

pbio = BIO_new_file(pCertFile,"w");
if(NULL == pbio)
...{
return -1;
}

if(!PEM_write_bio_X509(pbio,pCert))
...{
printf("save_cert:call PEM_write_bio_X509 error ");
return -1;
}

BIO_free(pbio);
return 0;
}

/**//*读取配置文件*/
int read_config()
...{
read_init();
return 0;
}

void add_subject_entity(char *key, char *value)
...{
int nid;
X509_NAME_ENTRY *ent;
if( (nid =OBJ_txt2nid(key)) == NID_undef )
...{
printf(" add_subject_entity:concert nid error");
return ;
}

ent = X509_NAME_ENTRY_create_by_NID(NULL,nid,MBSTRING_UTF8,
(unsigned char*)value,-1);
if(ent == NULL)
...{
printf("add_subject_entity:create ent error");
return;
}

if(X509_NAME_add_entry(pSubjectName,ent,-1,0) != 1)
...{
printf("add_subject_entity:add to subjectname error");
return;
}
return;
}

int create_req()
...{
/**//*读取配置文件*/
if(0 != read_config())
...{
return -1;
}

/**//*申请请求内存*/
req = X509_REQ_new();

/**//*创建密钥对*/
pNewRsaKey = EVP_PKEY_new();
EVP_PKEY_assign_RSA(pNewRsaKey, RSA_generate_key(512,0x10001,NULL,NULL));
X509_REQ_set_pubkey(req,pNewRsaKey);

/**//*保存密钥对*/
if(0 != save_rsa_key(pNewRsaKey))
...{
printf("call save_rsa_key error ");
return -1;
}

pSubjectName = X509_NAME_new();
if(pSubjectName == NULL)
...{
printf("create_req_demo:create subjectname error ");
return -1;
}

/**//*添加实体字段*/
add_subject_entity("countryName", szCountry);
add_subject_entity("stateOrProvinceName", szState);
add_subject_entity("localityName", szLocation);
add_subject_entity("organizationName", szOrganization);
add_subject_entity("commonName", szCommonName);

/**//*添加实体*/
if(1 != X509_REQ_set_subject_name(req,pSubjectName))
...{
printf("create_req_demo:add subjectname to req error");
return -1;
}

return 0;
}

void create_cert_demo()
...{
int ret = 0;
X509 *certTmp =NULL;
X509 *pCaCert = NULL;
X509_NAME *pName=NULL;//X509_NAME_new();
EVP_PKEY *pCaRsaKey = NULL;
char szRsaKeyFileName[256] = ...{0};

/**//*创建请求*/
ret = create_req();
if (0 != ret)
...{
return;
}

/**//*if (!strcmp(szIsser, "SELF") || 0 == szIsser[0])
{
isCa = 1;
}
else*/
if(0 == isCa)
...{
if(0 != read_cert(&pCaCert, szIsser))
...{
printf("read cert error ");
return;
}
}

/**//*申请内存*/
certTmp = X509_new();
if (NULL == certTmp)
...{
printf("内存申请失败");
return;
}

/**//*设置版本号:V3*/
ret = X509_set_version(certTmp, MA_X509_V3);
if (ret != 1)
...{
printf("设置证书版本错误:0x%x",ret);
return;
}

/**//*设置序列号*/
ret = ASN1_INTEGER_set(X509_get_serialNumber(certTmp),ulSn);
if (ret != 1)
...{
printf("设置序列号错误:0x%x", ret);
return;
}

/**//*设置开始时间*/
if(!X509_gmtime_adj(X509_get_notBefore(certTmp),0))
...{
printf("设置开始时间失败:0x%x", ret);
return;
}

if (!X509_gmtime_adj(X509_get_notAfter(certTmp), (long)60*60*24*10))
...{
printf("设置结束时间失败");
}

if (!X509_set_subject_name(certTmp, X509_REQ_get_subject_name(req)))
...{
printf("设置请求失败");
}

EVP_PKEY *tmppkey = X509_REQ_get_pubkey(req);
if (!tmppkey || !X509_set_pubkey(certTmp,tmppkey))
...{
EVP_PKEY_free(tmppkey);
printf("设置公钥失败");
}
EVP_PKEY_free(tmppkey);

if(1 == isCa)
...{
pName = X509_REQ_get_subject_name(req);
}
else
...{
pName = X509_get_subject_name(pCaCert);
}

if(NULL == pName)
...{
printf("get issuer name error ");
return;
}

if (!X509_set_issuer_name(certTmp, pName))
...{
printf("设置签发者名字失败 ");
return;
}

if(1 == isCa)
...{
X509_sign(certTmp, pNewRsaKey, EVP_sha1());
}
else
...{
if(0 != read_rsa_key(&pCaRsaKey, szCaRsaKeyFileName, (unsigned char *)szX509RsaPswd))
...{
printf("read rsa key error ");
return;
}
X509_sign(certTmp, pCaRsaKey, EVP_sha1());
}

/**//**********************************************
BIO *pbio;
pbio = BIO_new(BIO_s_mem());
PEM_write_bio_X509(pbio,certTmp);
BUF_MEM * bptr;
BIO_get_mem_ptr(pbio,&bptr);

char *buf = (char *)malloc(bptr->length);
if(NULL == buf)
{
printf("malloc error");
return;
}

memcpy(buf, bptr->data, bptr->length);
printf("%s ", buf);
**********************************************/

if(0 == save_cert(certTmp, szCertFileName))
...{
printf("create cert successfully, cert file name is %s ", szCertFileName);
return;
}
return;
}

int main(int argc, char* argv[])
...{
create_cert_demo();
system("pause");
return 0;
}

所谓数字 证书 ,是一种用于电脑的身份识别机制。由数字 证书 颁发机构(CA)对 使用 私钥创建的 签名 请求文件做的 签名 (盖章),表示CA结构对 证书 持有者的认可。数字 证书 拥有以下几个优点: 使用 数字 证书 能够提高用户的可信度 数字 证书 中的公钥,能够与服务端的私钥配对 使用 实现 数据传输过程中的加密和解密 在证认 使用 者身份期间, 使用 者的敏感个人数据并不会被传输至 证书 持有者的网络系统上 X.509 证书 gmssl编程之签发 证书 前言命令行 实现 方式编程 实现 方式step1. 产生密钥对step2. 生成 证书 请求step3. 签发X509源代码 最近由于项目需求,需要通过代码组装并签发标准X509格式数字 证书 。故而查询资料对gmssl/ openssl 中签发 证书 流程就行了一番研究,终于完成。先记录如下. 命令行 实现 方式 命令行方式下 使用 gmssl/ openssl 指令进行 证书 签发主要有三步:生成密钥对(私钥)、生成 证书 请求、签发 证书 。 具体小伙伴们可参考小编这篇文章:Gmssl生成自 签名 证书 编程 实现 方式 作者:肖波背景服务器SSL数字 证书 和客户端单位数字 证书 的格式遵循X.509标准。X.509是由国际电信联盟(ITU-T)制定的数字 证书 标准。为了提供公用网络用户目录信息服务,ITU于1988年制定了X.500系列标准。其中X.500和X.509是安全认证系统的核心,X.500定义了一种区别命名规则,以命名树来确保用户名称的唯一性;X.509则为X.500用户名称提供了通信实体鉴别机制,并规定了实体... openssl 数字 证书 使用 pg openssl types扩展时,我意识到我还没有讨论如何 使用 OpenSSL 库对数字 证书 进行 签名 。 (至少我不记得这样做了–我可能在博客的早期就对此进行了讨论。我敢肯定,我已经讨论过 使用 BouncyCastle(java)库对数字 证书 进行 签名 。) 我的pg openssl types扩展将具有 签名 数字 证书 以进行测试的能力,但实际工作将在可能的pgca扩展中完成... // X509_Cert_Class.h: interface for the X509_Cert_Class class. ////////////////////////////////////////////////////////////////////// #if !defined(AFX_X509_CERT_CLASS_H__CFDD9091_CC06_404A_9 > openssl x509 -req -in xxx/xxx-req.csr -out xxx/xxx-cert.pem -signkey xxx/xxx-key.pem -CA ca/ca-cert.pem -CAkey ca/root-key.pem -CAcreateserial -days 3650 ##签署服务器 证书 。$> openssl req -new -out xxx/xxx-req.csr -key xxx/xxx-key.pem ##创建 证书 请求。