使用OpenSSL创建包含自签名、本地测试分发点CRL的CMS signedData(M3 Mac)

使用OpenSSL创建包含CRL的CMS signedData


前提:
已安装vscode、openssl

撤销rsacert-plus-revoke.crt

配置CRL服务器:在准备放crl.pem的位置终端

python3 -m http.server

编辑openssl.cnf配置crl分发点

[ v3_ca ]
# ... other settings ...
crlDistributionPoints = URI:http://localhost:8000/crl.pem

生成证书,openssl x509和openssl ca都可以颁发证书,但是需要在证书的扩展字段添加crl的颁发点,就需要使用openssl ca
生成csr
注:commonName不可为空,输入的是CN

openssl req -new -key rsakey2048.pem -out rsacert-plus.csr
openssl ca -extensions v3_ca -in rsacert-plus.csr -out rsacert-plus.crt

再生成一个被撤销的证书,一样的命令,但是commonName输入CN2

openssl req -new -key rsakey2048.pem -out rsacert-plus-revoke.csr
openssl ca -extensions v3_ca -in rsacert-plus-revoke.csr -out rsacert-plus-revoke.crt

由于配置文件里写死了cakey.pem的文件名
所以自己生成目录和目录下的文件,会在撤销时找./demoCA/private/cakey.pem
./demoCA/cacert.pem
创建目录和文件

mkdir demoCA
mkdir demoCA/newcerts
mkdir demoCA/private
touch demoCA/index.txt
echo 01 > demoCA/serial
echo 01 > demoCA/crlnumber

生成CA密钥和证书

cd ./demoCA/private
openssl req -newkey isa:2048 -nodes -keyout cakey.pem -x509 -days 365 -out cacert.pem
mv cacert.pem ../

撤销证书

cd ../..
openssl ca -revoke ./rsacert—plus-revoke.crt

生成crl

openssl ca -gencrl -out ./crl.pem

创建CMS

生成不含crl的cms

openssl cms -sign -in temp.txt -outform DER -signer rsacert-plus.crt -inkey rsakey2048.pem -out cms-plus.der

openssl不支持使用命令行创建包含crl的cms,需要自己编写代码来调用openssl的API来创建
查看openssl的安装路径:
which openssl
在vscode里编写代码,

#include <openssl/cms.h>
#include <openssl/bio.h>
#include <openssl/x509.h>
#include <openssl/x509_vfy.h>
#include <openssl/pem.h>
#include <openssl/err.h>

int add_crl_to_cms(const char *cms_in_path, const char *crl_path, const char *cms_out_path) {
    BIO *cms_bio = NULL;
    BIO *crl_bio = NULL;
    BIO *out_bio = NULL;
    X509_CRL *crl = NULL;
    CMS_ContentInfo *cms = NULL;
    int ret = 1; // 失败为1,成功为0

    // 读取CMS文件
    cms_bio = BIO_new_file(cms_in_path, "rb");
    if(!cms_bio){
        fprintf(stderr, "读取cms失败\n");
        goto err;
    }
    cms = d2i_CMS_bio(cms_bio, NULL);
    if(!cms){
        fprintf(stderr, "解析cms失败\n");
        goto err;
    } 

    // 读取CRL文件
    crl_bio = BIO_new_file(crl_path, "rb");
    if(!crl_bio){
        fprintf(stderr, "读取crl失败\n");
        goto err;
    }
    crl = PEM_read_bio_X509_CRL(crl_bio, NULL, 0, NULL);
    if(!crl){
        fprintf(stderr, "解析crl失败\n");
        goto err;
    } 

    // 添加CRL到CMS
    if(!CMS_add0_crl(cms, crl)){
        fprintf(stderr, "添加CRL到CMS失败\n");
        goto err;
    } 

    // 写CMS到文件
    out_bio = BIO_new_file(cms_out_path, "wb");
    if(!out_bio){
        fprintf(stderr, "创建输出文件失败\n");
        goto err;
    } 
    if(!i2d_CMS_bio(out_bio, cms)){
        fprintf(stderr, "写入CMS到文件失败\n");
        goto err;
    } 

    ret = 0; // 成功

err:
    if(ret != 0) ERR_print_errors_fp(stderr);
    if(cms_bio) BIO_free(cms_bio);
    if(crl_bio) BIO_free(crl_bio);
    if(out_bio) BIO_free(out_bio);
    if(cms) CMS_ContentInfo_free(cms);
    if(crl) X509_CRL_free(crl);
    return ret;
}

int main(int argc, char *argv[]) {
    // 检查命令行参数
    if(argc != 4) {
        fprintf(stderr, "用法: %s <cms输入路径> <crl路径> <cms输出路径>\n", argv[0]);
        return 1;
    }
    
    // 调用函数添加CRL到CMS
    if(add_crl_to_cms(argv[1], argv[2], argv[3]) != 0) {
        fprintf(stderr, "添加CRL到CMS失败\n");
        return 1;
    }

    printf("CRL已成功添加到CMS\n");
    return 0;
}

编译:在vscode的终端使用gcc编译
注:-lssl -lcrypto是必须的,-L后面和-I后面换成自己之前which openssl的路径

gcc cms.c -o cms -L/opt/homebrew/opt/openssl/lib -I/opt/homebrew/opt/openssl/include -lssl -lcrypto

然后再运行cms

sudo ./cms ./cms-plus.der ./crl.pem ./cms-plus-full.der

验证CMS

openssl cms -verify -inform DER -in cms-plus.der -content temp.txt -signer rsacert-plus.crt -CAfile ./demoCA/cacert.pem

结果:

CMS Verification successful
  • 8
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

sunny_cube

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值