本文主要介绍如果在C++中使用OpenSSL的证书相关API。(基于OpenSSL 1.0.2k版本,不同版本可能API会有一些差异,但大体应该类似)
使用下面方法前,需要全局调用一次(无需多次调用)
OpenSSL_add_all_algorithms();
1、生成公私钥对
BIGNUM *bne = NULL;
int bits = RSAKeyBits;
unsigned long e = RSA_F4;
int ret = 0;
bne = BN_new();
int r = BN_set_word(bne,e);
if(r != 1){
goto free_all;
}
if(m_rsa)
{
RSA_free(m_rsa);
m_rsa = NULL;
}
// m_rsa是成员变量,用于存储公私钥对
m_rsa = RSA_new();
r = RSA_generate_key_ex(m_rsa, bits, bne, NULL);
if(r != 1){
goto free_all;
}
free_all:
BN_free(bne);
2、生成CSR
X509 *x509 = NULL;
X509_NAME *subject = NULL;
BIO *bio = NULL;
X509_REQ *x509Req = NULL;
char *szCSR = NULL;
// 提取私钥
EVP_PKEY_assign_RSA(m_pKey, m_rsa);
x509 = X509_new();
X509_set_pubkey(x509, m_pKey);
// 设置属性
subject = X509_get_subject_name(x509);
// 国家
X509_NAME_add_entry_by_txt(subject, SN_countryName, MBSTRING_UTF8,
(unsigned char *)"CN", -1, -1, 0);
// 省份
X509_NAME_add_entry_by_txt(subject, SN_stateOrProvinceName, MBSTRING_UTF8,
(unsigned char *)"GuangDong", -1, -1, 0);
// 城市
X509_NAME_add_entry_by_txt(subject, SN_localityName, MBSTRING_UTF8,
(unsigned char *)"ShenZhen", -1, -1, 0);
X509_set_subject_name(x509, subject);
x509Req = X509_to_X509_REQ(x509, m_pKey, ShaFunc);
if(!x509Req)
{
goto free_all;
}
// 可视化输出
bio = BIO_new(BIO_s_mem());
PEM_write_bio_X509_REQ(bio, x509Req);
if(bio->num_write == 0)
{
goto free_all;
}
szCSR = (char*)malloc(bio->num_write+1);
if(!szCSR)
{
goto free_all;
}
memset(szCSR, 0, bio->num_write+1);
BIO_read(bio, szCSR, bio->num_write);
free_all:
if(x509)
X509_free(x509);
if(x509Req)
X509_REQ_free(x509Req);
if(bio)
BIO_free(bio);
if(szCSR)
free(szCSR);
3、生成证书