openssl PKCS7_sign 只构造PKCS7签名结构不签名
openssl PKCS7_sign()函数用于将给定的数据用私钥进行签名,并构造出PKCS7签名结构。该函数只构造PKCS7签名结构,不会实际进行签名操作。签名操作需要调用PKCS7_sign_add_signer()函数进行。
函数原型如下:
PKCS7 *PKCS7_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs, BIO *data, int flags);
参数说明:
- signcert:签名证书,即用于进行签名的证书。
- pkey:私钥,即用于进行签名的私钥。
- certs:证书链,即签名证书的证书链。
- data:待签名数据的BIO对象。
- flags:PKCS7签名选项,可以为0或者PKCS7_DETACHED(表示签名结果与原始数据分开)。
返回值:
- PKCS7类型的指针,表示PKCS7签名结构。
示例代码:
// 使用私钥进行签名,构造PKCS7签名结构
PKCS7 *pkcs7_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs, BIO *data) {
// 构造PKCS7签名结构
PKCS7 *p7 = PKCS7_new();
if (!p7) {
return NULL;
}
// 设置PKCS7签名类型为NID_pkcs7_signed
if (!PKCS7_set_type(p7, NID_pkcs7_signed)) {
PKCS7_free(p7);
return NULL;
}
// 构造PKCS7签名者信息
PKCS7_SIGNER_INFO *si = PKCS7_SIGNER_INFO_new();
if (!si) {
PKCS7_free(p7);
return NULL;
}
// 设置PKCS7签名者证书
if (!PKCS7_SIGNER_INFO_set_cert(si, signcert)) {
PKCS7_SIGNER_INFO_free(si);
PKCS7_free(p7);
return NULL;
}
// 设置PKCS7签名者私钥
if (!PKCS7_SIGNER_INFO_set0_pkey(si, pkey)) {
PKCS7_SIGNER_INFO_free(si);
PKCS7_free(p7);
return NULL;
}
// 设置PKCS7签名者证书链
if (certs && sk_X509_num(certs) > 0) {
PKCS7_SIGNER_INFO_set1_signer_certs(si, certs);
}
// 将PKCS7签名者信息添加到PKCS7签名结构中
if (!PKCS7_add_signer(p7, si)) {
PKCS7_SIGNER_INFO_free(si);
PKCS7_free(p7);
return NULL;
}
// 设置PKCS7签名选项
int flags = PKCS7_DETACHED;
// 构造PKCS7签名数据
PKCS7 *ret = PKCS7_sign(signcert, pkey, certs, data, flags);
if (!ret) {
PKCS7_free(p7);
return NULL;
}
// 将PKCS7签名结构添加到PKCS7签名者信息中
if (!PKCS7_add_signed_attribute(si, NID_pkcs7_data, V_ASN1_OBJECT, (void *) OBJ_nid2obj(NID_pkcs7_data))) {
PKCS7_free(p7);
return NULL;
}
if (!PKCS7_add_signed_attribute(si, NID_pkcs7_digest, V_ASN1_OBJECT, (void *) OBJ_nid2obj(NID_sha256))) {
PKCS7_free(p7);
return NULL;
}
if (!PKCS7_add_signed_attribute(si, NID_pkcs9_contentType, V_ASN1_OBJECT, (void *) OBJ_nid2obj(NID_pkcs7_data))) {
PKCS7_free(p7);
return NULL;
}
// 清理资源
PKCS7_SIGNER_INFO_free(si);
PKCS7_free(ret);
return p7;
}
``
原文地址: https://www.cveoy.top/t/topic/c4gf 著作权归作者所有。请勿转载和采集!