opensll 证书及CRL生成

阅读: 评论:0

opensll 证书及CRL生成

opensll 证书及CRL生成

证书生成

通用命令

查看摘要算法列表
openssl list -digest-algorithms
openssl crl -in crl.pem -text 查看信息
openssl x509 -in cert.pem -text

1、sm2证书生成

生成私钥

openssl ecparam -genkey -name SM2 -out private_key.pem

(RSA 公钥的字节结构可以使用标准的SubjectPublicKeyInfo(SPKI)格式来表示。这个格式由一系列的 DER 编码的 ASN.1 结构组成)
用私钥生成公钥

openssl ec -in private_key.pem -pubout -out sm2PubKey.pem

生成证书
1)生成配置文件f

[ req ]
default_bits = 256
prompt = no
default_md = sm3
distinguished_name = dn
[ dn ]
C = CN
ST = Beijing
L = Beijing
O = Your Organization
OU = Your Unit
CN = Your Common Name

default_bits:指定生成的密钥长度,默认为 256 位。在 SM2 中,通常使用 256 位曲线。
prompt:设置是否显示提示信息。在此示例中,设置为 no,即不显示提示信息。
default_md:指定摘要算法类型,默认为 SM3。SM3 是中国国家标准的密码杂凑算法,用于计算数字签名和生成证书请求。
distinguished_name:指定证书主题的字段。
C:国家名(Country),两个字母的国家代码。例如,CN 表示中国。
ST:省/自治区/直辖市名(State/Province/Region)。
L:地区/城市名(Locality/City)。
O:组织名(Organization)。
OU:组织单位名(Organizational Unit)。
CN:通用名称(Common Name),即证书的主题。
2)用私钥和配置文件生成证书
openssl req -new -key private_key.pem -out cert_req.csr -f

不使用配置文件的时候

openssl req -x509 -key private_key.pem -out certificate.pem -days 365 -config <(echo "[ req ]ndefault_bits = 256nprompt = nondefault_md = SM3ndistinguished_name = dnn[ dn ]nC = CNnST = SCnL = ChengdunO = zdxlznOU = zdxlznCN = Test")

易错点

140345702581568:error:100C508A:elliptic curve routines:pkey_ec_ctrl:invalid digest type:../crypto/ec/ec_pmeth.c:331

openssl 1.1.1版本后支持国密算法(去掉default_md = sm3)

2、CRL生成

介绍
包含撤销的证书列表的签名数据结构,类似于信用卡的黑名单,公布某些数字证书无效。
CRL可以分为完全CRL和增量CRL。在完全CRL中包含了所有的被撤销证书信息,增量CRL由一系列的CRL来表明被撤销的证书信息,它每次发布的CRL是对前面发布CRL的增量扩充。
基本的CRL信息有:被撤销证书序列号、撤销时间、撤销原因、签名者以及CRL签名等信息。
基于CRL的验证是一种不严格的证书认证。CRL能证明在CRL中被撤销的证书是无效的。但是,它不能给出不在CRL中的证书的状态。如果执行严格的认证,需要采用在线方式进行认证,即OCSP认证。

结构体

typedef struct X509_revoked_st//一个被撤销证书的信息
{ASN1_INTEGER *serialNumber;//被撤销证书的序列号;ASN1_TIME *revocationDate;//撤销时间STACK_OF(X509_EXTENSION) *extensions;//扩展项,可选int sequence;//顺序号,用于排序,表示当前被撤销证书信息在crl中的顺序
} X509_REVOKED;
//主体信息
typedef struct X509_crl_info_st
{ASN1_INTEGER *version;//crl版本X509_ALGOR *sig_alg;//crl签名法X509_NAME *issuer;//签发者信息ASN1_TIME *lastUpdate;//上次更新时间ASN1_TIME *nextUpdate;//下次更新时间STACK_OF(X509_REVOKED) *revoked;//被撤销证书信息STACK_OF(X509_EXTENSION) *extensions;//ASN1_ENCODING enc;//
} X509_CRL_INFO;
// 完整crl数据结构
struct X509_crl_st
{X509_CRL_INFO *crl;//crl信息主体X509_ALGOR *sig_alg;//签名算法,与X509_CRL_INFO中的一致ASN1_BIT_STRING *signature;//签名值int references;//引用
} ;

函数

int X509_CRL_add0_revoked(X509_CRL *crl, X509_REVOKED *rev)//添加一个被撤销证书的信息
int X509_CRL_print(BIO *bp,X509_CRL *x)//打印crl内容到BIO中
int X509_CRL_print_fp(FILE *fp, X509_CRL *x)//将crl的内容输出到fp中,此函数调用了X509_CRL_print
int X509_CRL_set_issuer_name(X509_CRL *x, X509_NAME *name)//设置crl的颁发者
int X509_CRL_set_lastUpdate(X509_CRL *x, ASN1_TIME *tm)//设置crl上次发布时间
int X509_CRL_set_nextUpdate(X509_CRL *x, ASN1_TIME *tm)//设置crl下次发布时间
int X509_CRL_set_version(X509_CRL *x, long version)//设置crl版本
int X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md)//对crl进行签名,pkey为私钥,md为摘要算法,结果存放在x-> signature中
int X509_CRL_sort(X509_CRL *c)//根据证书序列号对crl排序,此函数实现采用了堆栈排序,堆栈的比较函数为X509_REVOKED_cmp(crypto/asn1/x_crl.c)
//添加CRL扩展,nid为要添加的扩展标识,value为被添加的具体扩展项的内部数据结构地址,crit表明是否为关键扩展,flags表明何种操作。此函数调用X509V3_add1_i2d函数
int X509_CRL_add1_ext_i2d(X509_CRL *x, int nid, void *value, int crit,  unsigned long flags)
int X509_CRL_add_ext(X509_CRL *x, X509_EXTENSION *ex, int loc)//添加扩展项到指定堆栈位置,此函数调用X509v3_add_ext,进行堆栈插入操作。
int X509_CRL_cmp(const X509_CRL *a, const X509_CRL *b)//CRL比较,此函数调用X509_NAME_cmp,只比较颁发者的名字是否相同。
X509_EXTENSION *X509_CRL_delete_ext(X509_CRL *x, int loc)//删除CRL扩展项堆栈中的某一项,loc指定被删除项在堆栈中的位置
int X509_CRL_digest(const X509_CRL *data, const EVP_MD *type,unsigned char *md, unsigned int *len)//CRL摘要,本函数对X509_CRL进行摘要,type指定摘要算法,摘要结果存放在md中,len表明摘要结果长度
X509_CRL *X509_CRL_dup(X509_CRL *crl);
void *X509_CRL_get_ext_d2i(X509_CRL *x, int nid, int *crit, int *idx)//CRL中的获取扩展项,此函数用于获取crl中指定扩展项的内部数据结构,返回值为具体的扩展项数据结构地址,nid为扩展项标识,它调用了X509V3_get_d2i函数。
int X509_CRL_get_ext_by_critical(X509_CRL *x, int crit, int lastpos)
int X509_CRL_get_ext_by_NID(X509_CRL *x, int nid, int lastpos)
int X509_CRL_get_ext_by_OBJ(X509_CRL *x, ASN1_OBJECT *obj, int lastpos)
int X509_CRL_get_ext_count(X509_CRL *x)//获取crl中扩展项的个数
int X509_CRL_verify(X509_CRL *a, EVP_PKEY *r)//验证CRL。EVP_PKEY结构r中需要给出公钥(与签名相对应的)验证内容:签名,签发者证书,验证crl完整性
long X509_CRL_get_version(const X509_CRL *crl);//获取版本号
X509_NAME *X509_CRL_get_issuer(const X509_CRL *crl);//获取颁发者名称
char *X509_NAME_oneline(const X509_NAME *a, char *buf, int size);//将 X.509 证书的主题或颁发者(发行者)的名称转换为可打印的字符串形式
ASN1_TIME *X509_CRL_get_lastUpdate(X509_CRL *crl)
ASN1_TIME *X509_CRL_get_nextUpdate(X509_CRL *crl)
STACK_OF(X509_REVOKED) *X509_CRL_get_REVOKED(X509_CRL *crl);//用于获取撤销证书列表,该函数返回一个 STACK_OF(X509_REVOKED) 结构的指针,即撤销证书的列表。STACK_OF(X509_REVOKED) 是 OpenSSL 提供的一种堆栈数据结构,用于存储多个 X509_REVOKED(被撤销的证书)对象
static inline int sk_X509_REVOKED_num(const stack_st_X509_REVOKED *sk)//获取 STACK_OF(X509_REVOKED) 结构中元素数量的函数
static inline x509_revoked_st *sk_X509_REVOKED_value(const stack_st_X509_REVOKED *sk, int idx)//获取指定索引位置的元素的函数,返回撤销证书列表中指定索引位置的被撤销证书对象
const ASN1_INTEGER *X509_REVOKED_get0_serialNumber(const X509_REVOKED *x);// 获取被撤销证书的序列号
unsigned char *ASN1_STRING_data(ASN1_STRING *x)//获取 ASN1_STRING 结构中数据的指针	
int ASN1_STRING_length(const ASN1_STRING *x);//用于获取 ASN1_STRING 结构中数据的长度
ASN1_INTEGER *X509_get_serialNumber(X509 *x);//获取证书序列号

1、配置文件f

[ca]
default_ca = CA_default  	CA 的默认设置[CA_default]
dir = /path/to/CA/folder
crl_dir = $dir/crl  		指定存放 CRL 文件的文件夹路径
database = $ 	 指定用于存储证书签发和撤销信息的数据库文件(索引文件)路径。该文件记录了已颁发的证书和被撤销的证书的相关信息。
serial = $dir/serial		指定一个用于跟踪证书序列号的文件路径。每当颁发一个新证书时,该文件中的序列号将递增。
private_key = /path/to/ca.key	指定 CA 的私钥文件路径。CRL 是由 CA 使用其私钥签名的
certificate = /path/	指定 CA 的证书文件路径。该证书将包含在生成的 CRL 中。
crlnumber = $dir/crlnumber		指定存储 CRL 号码的文件路径。每次生成 CRL 时,该号码将递增。
default_crl_days = 30			指定生成的 CRL 的默认有效期(以天为单位)。在生成 CRL 时可以覆盖此值.[crl_ext] 						CRL 扩展字段的部分
issuerAltName=issuer:copy		指定 CRL 的颁发者别名,以及将从 CA 证书中拷贝的颁发者信息。
authorityKeyIdentifier=keyid:always	声明 CRL 中的颁发者密钥标识符(AKI)字段始终包含在 CRL 中[req]	
default_bits = 2048				
prompt = no						控制是否在生成证书请求时提示用户输入信息。将其设置为 "no" 可以禁用提示,使用默认值填充
default_md = sha256				指定证书签名所使用的消息摘要算法,默认为 SHA256
distinguished_name = dn			定义证书主题(Subject)的字段信息[dn]
CN = Your CA Name				
部分参数可忽略
openssl ca -f -gencrl -out crl.pem

测试程序

#include "x509.h"
#include "pem.h"
#include "ossl_typ.h"
#include "../third-Part/openssl/include/crypto/x509.h"
#include "../third-Part/openssl/include/crypto/asn1.h"
#include "Debug.h"
#include "parseCRL.h"
#include "parseCertTest.h"void parseCRL(char *fileStr, X509 *cert)
{FILE *crlFile = fopen(fileStr, "r");if(crlFile == NULL){debugPrintf("crlFile fopen err n");return;}X509_CRL *crl = NULL;//PEM 文件的指针, 指向 X509_CRL 结构体指针的指针(读取到才有), 指向密码回调函数的指针,用户数据指针crl = PEM_read_X509_CRL(crlFile, &crl, NULL, NULL);if(crl == NULL){debugPrintf("PEM_read_X509_CRL err n");return;}//DER格式读取
//    BIO *crl_bio = BIO_new_file(fileStr, "r");
//    crl = d2i_X509_CRL_bio(crl_bio, NULL);
//    BIO_free(crl_bio);//获取版本号long version = X509_CRL_get_version(crl);debugPrintf("version %ldn", version);X509_NAME *issuer_name = X509_CRL_get_issuer(crl);char *issuer_str = X509_NAME_oneline(issuer_name, NULL, 0);debugPrintf("Issuer: %sn", issuer_str);X509_ALGOR *sig_alg = &crl->sig_alg;//将一个对象的数字标识符(NID)转换为对应的短名(SN)const char *alg_name = OBJ_nid2sn(sig_alg->algorithm->nid);debugPrintf("Signature Algorithm: %sn", alg_name);// 获取上次更新时间和下次更新时间ASN1_TIME *last_update = X509_CRL_get_lastUpdate(crl);ASN1_TIME *next_update = X509_CRL_get_nextUpdate(crl);printASN1Time(last_update);printASN1Time(next_update);// 获取撤销列表,栈STACK_OF(X509_REVOKED) *revoked_list = X509_CRL_get_REVOKED(crl);int num_revoked = 0;if (revoked_list != NULL) {//获取revoked_list中的数量num_revoked = sk_X509_REVOKED_num(revoked_list);// 遍历撤销的证书列表}X509_REVOKED *revoked_cert;ASN1_INTEGER *serial_number;for (int i = 0; i < num_revoked; i++) {//获取指定索引位置的元素的函数,返回撤销证书列表中指定索引位置的被撤销证书对象revoked_cert = sk_X509_REVOKED_value(revoked_list, i);// 获取被撤销证书的序列号serial_number = X509_REVOKED_get0_serialNumber(revoked_cert);// 打印序列号,获取 ASN1_STRING 结构中数据的指针char *hex_serial = (char *)ASN1_STRING_data(serial_number);int hex_serial_len = ASN1_STRING_length(serial_number);for (int j = 0; j < hex_serial_len; j++) {printf("%02X", hex_serial[j]);}printf("n");}
//获取证书序列号,验证吊销列表int isRevoked = 0;ASN1_INTEGER *cert_serial = X509_get_serialNumber(cert);for (int i = 0; i < num_revoked; ++i) {revoked_cert = sk_X509_REVOKED_value(revoked_list, i);serial_number = X509_REVOKED_get0_serialNumber(revoked_cert);// 比较证书的序列号if (ASN1_INTEGER_cmp(cert_serial, serial_number) == 0) {isRevoked = 1;break;}}debugPrintf("check serialNumber n");
}

说明
结合证书校验代码,测试用该证书生成的crl(如果获取的吊销列表为空,注意crl配置文件里面的证书吊销的序列号是否有)。
DER格式和PEM格式略有不同

static void _getASN1Time(ASN1_TIME* Time, char *rcvTime)
{//BIO是一种用于进行输入/输出操作的抽象类型。它提供了一种统一的接口,可用于在不同的数据源和目标之间进行读写操作。BIO* bio = BIO_new(BIO_s_mem());if (bio == NULL) {return;}if (ASN1_TIME_print(bio, Time) <= 0) {BIO_free(bio);return;}char buf[1024];//从bio对象中读取结果int len = BIO_read(bio, buf, sizeof(buf) - 1);if (len <= 0) {BIO_free(bio);return;}buf[len] = '';memcpy(rcvTime, buf, len);BIO_free(bio);
}
/*** 从字节流或字节数组读取证书结构存储X509* @param buffer    证书数据* @param size      大小* @param crl       返回的证书* @return  0成功*/
int crlInit(unsigned char* buffer, int size, X509_CRL **crl)
{TRACE_INFO("crlInit");TRACE_HEX_DUMP("buffer", buffer, size);//der格式X509_CRL* _crl = d2i_X509_CRL(NULL, &buffer, size);if (_crl != NULL){TRACE_INFO("d2i_X509_CRL err");} else{BIO *bio = BIO_new_mem_buf(buffer, -1);//pem格式_crl = PEM_read_bio_X509_CRL(bio, NULL,NULL,NULL);if(_crl ==NULL){TRACE_INFO("read crl err");return -1;}}*crl = _crl;//值传递return 0;
}
/*** 获取基本crl基本信息* @param crl   输入crl* @param x509_CRL_INFO 返回的结构体信息* @return*/
int crlGetInfo(X509_CRL *crl, _X509_CRL_INFO *x509_CRL_INFO)
{if(x509_CRL_INFO == NULL){TRACE_INFO("x509_CRL_INFO NULL");return -1;}x509_CRL_INFO->version = X509_CRL_get_version(crl) + 1;if(X509_CRL_get_issuer(crl) != NULL){X509_NAME *issuer_name = X509_CRL_get_issuer(crl);char *issuer_str = X509_NAME_oneline(issuer_name, NULL, 0);x509_CRL_INFO->issuer_name_len = (int)strlen(issuer_str);x509_CRL_INFO->issuer_name = issuer_str;}X509_ALGOR *sig_alg = &crl->sig_alg;//将一个对象的数字标识符(NID)转换为对应的短名(SN)const char *alg_name = OBJ_nid2sn(sig_alg->algorithm->nid);memcpy(x509_CRL_INFO->alg_name, alg_name, strlen(alg_name));ASN1_TIME *thisUpdate = X509_CRL_get_lastUpdate(crl);ASN1_TIME *nextUpdate = X509_CRL_get_nextUpdate(crl);_getASN1Time(thisUpdate,x509_CRL_INFO->thisUpdate);_getASN1Time(nextUpdate,x509_CRL_INFO->nextUpdate);if(crl->signature.data != NULL){x509_CRL_INFO->signLen = crl->signature.length;x509_CRL_INFO->signDate = crl->signature.data;}if(crl->crl_number != NULL){x509_CRL_INFO->crlNumber_len = crl->crl_number->length;x509_CRL_INFO->crlNumber = crl->crl_number->data;}if(crl->crl_number != NULL){x509_CRL_INFO->base_crl_number_len = crl->base_crl_number->length;x509_CRL_INFO->base_crl_number = crl->base_crl_number->data;}return 0;
}
/**** @param crl  输入 x509 crl* @param cert_serial   输入需要校验证书的序列号* @return  1 证书合法不在吊销列表,0校验失败,证书不合法*/
int crlCheckRevokedList(X509_CRL *crl, ASN1_INTEGER *cert_serial)
{STACK_OF(X509_REVOKED) *revoked_list = X509_CRL_get_REVOKED(crl);int num_revoked = 0;if (revoked_list != NULL){num_revoked = sk_X509_REVOKED_num(revoked_list);} else{TRACE_INFO("X509_CRL_get_REVOKED NULL");return 1;}X509_REVOKED *revoked_cert;ASN1_INTEGER *serial_number;for (int i = 0; i < num_revoked; i++) {//获取指定索引位置的元素的函数,返回撤销证书列表中指定索引位置的被撤销证书对象revoked_cert = sk_X509_REVOKED_value(revoked_list, i);// 获取被撤销证书的序列号serial_number = X509_REVOKED_get0_serialNumber(revoked_cert);char *hex_serial = (char *)ASN1_STRING_data(serial_number);int hex_serial_len = ASN1_STRING_length(serial_number);TRACE_HEX_DUMP("hex_serial", hex_serial, hex_serial_len);//对比序列号是否是吊销列表if (ASN1_INTEGER_cmp(cert_serial, serial_number) == 0) {return 0;//查出吊销列表}}return 1;
}

本文发布于:2024-01-28 23:29:55,感谢您对本站的认可!

本文链接:https://www.4u4v.net/it/170645580011078.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:证书及   opensll   CRL
留言与评论(共有 0 条评论)
   
验证码:

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23