openssl命令行
1. 使用私钥证书cert.pem和私钥cert_pri.pem创建CMS格式签名。source.bin为签名前原始文件,source.bin.p7s为签名后文件:
openssl cms -sign -in source.bin -inkey cert_pri.pem -signer cert.pem -outform PEM -out source.bin.p7s -nodetach
2. CMS验证数字签名命令:
openssl cms -verify -in source.bin.p7s inform PEM -signer cert.pem -content source.bin -out temp.txt -no_signer_cert_verify -binary
CMS验签代码实现
// 读取p7s签名文件到BIO
BIO* bio_p7s = BIO_new_file(p7s_file, "rb");
// BIO转换为CMS签名结构体
CMS_ContentInfo *cms = d2i_CMS_ContentInfo(bio_p7s, NULL);
// 读取证书文件到BIO
BIO* bio_cert = BIO_new_file(cert_file, "rb");
// BIO DER编码转换为X509结构体
X509 *x509_cert = d2i_X509_bio(bio_cert, NULL);
// BIO base64格式证书读取
X509 *x509_cert = PEM_read_bio_X509(bio_cert, NULL, NULL, NULL);
// 创建证书集
STACK_OF(X509) *x509_certs = sk_X509_new_null();
// 添加到证书集
sk_X509_push(x509_certs, x509_cert);
// 创建证书存储区
X509_STORE* x509_store = X509_STORE_new();
// 将CA证书导入证书存储区
X509_STORE_add_cert(x509_store, x509_cert);
// 读取原文件内容
BIO* bio_content = BIO_new_file(content_file, "rb");
// flags设置一些模式,如CMS_NO_SIGNER_CERT_VERIFY表示不校验证书;CMS_BINARY表示
unsigned int flags = CMS_NO_SIGNER_CERT_VERIFY | CMS_BINARY;
// CMS 校验
// out可以为NULL或某文件BIO
int ret = CMS_verify(cms, x509_certs, x509_store, bio_content, NULL, flags);
// 释放资源
BIO_free_all(bio_p7s);
BIO_free_all(bio_cert);
BIO_free_all(bio_p7s);
X509_STORE_free(x509_store);
CMS_ContentInfo_free(cms);