Objective-C CMS签名的实现

通过私钥和证书封装成SMIME格式,并返回base64格式。基于openssl,参考openssl的demo,具体实现如下

- (NSString *) cmsSignStr : (NSString*) inputStr privateKey:(NSString*) inputPrv publicKey :(NSString *) inputPub
{
    NSString *retStr;
    const char *inputString = [inputStr cStringUsingEncoding:NSUTF8StringEncoding]; 
    const char *pvFileString = [inputPrv cStringUsingEncoding:NSASCIIStringEncoding];
    const char *pbFileString = [inputPub cStringUsingEncoding:NSASCIIStringEncoding];

    BIO *in = NULL, *out = NULL, *tbio = NULL, *b64 = NULL;
    X509 *scert = NULL, *scert2 = NULL;
    EVP_PKEY *skey = NULL, *skey2 = NULL;
    CMS_ContentInfo *cms = NULL;
    int ret = 1;

    OpenSSL_add_all_algorithms();
    ERR_load_crypto_strings();

    //读取X509证书
    tbio = BIO_new_file(pbFileString, "r");

    if (!tbio)
        goto err;

    scert2 = PEM_read_bio_X509(tbio, NULL, 0, NULL);

    BIO_reset(tbio);

    tbio = BIO_new_file(pvFileString, "r");

    skey2 = PEM_read_bio_PrivateKey(tbio, NULL, 0, NULL);

    if (!scert2 || !skey2)
        goto err;


    {
    in = BIO_new(BIO_s_mem());
    BIO_puts(in, inputString);

    if (!in)
        goto err;

    cms = CMS_sign(NULL, NULL, NULL, in, CMS_STREAM | CMS_PARTIAL);
    }
    if (!cms)
        goto err;

    /* 签名 */

    //    if (!CMS_add1_signer(cms, scert, skey, NULL, 0))
    //        goto err;

    if (!CMS_add1_signer(cms, scert2, skey2, NULL, 0))
        goto err;
    NSLog(@"CMS_add1_signer");

    if (!CMS_final(cms, in, NULL, 0)) {
        goto err;
    }
    NSLog(@"CMS_final");

    b64 = BIO_new(BIO_f_base64()); // create BIO to perform base64
    BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);

    out = BIO_new(BIO_s_mem()); // create BIO that holds the result

    // chain base64 with mem, so writing to b64 will encode base64 and write to mem.
    BIO_push(b64, out);

    /* NB: content included and finalized by SMIME_write_CMS */

//    if (!SMIME_write_CMS(out, cms, in, CMS_STREAM))
//        goto err;
    //生成2进制的文件
    if (!i2d_CMS_bio(b64, cms))
        goto err;

    NSLog(@"i2d_CMS_bio");


    BIO_flush(b64);
    NSLog(@"BIO_flush");

    char* pub_key;
    BIO_get_mem_data(b64, &pub_key);
    retStr = [NSString stringWithFormat:@"%s", pub_key ];

    NSLog(@"stringWithCString");

    ret = 0;

err:

    if (ret) {
        fprintf(stderr, "Error Signing Data\n");
        ERR_print_errors_fp(stderr);
    }

    if (cms)
        CMS_ContentInfo_free(cms);

    if (scert)
        X509_free(scert);
    if (skey)
        EVP_PKEY_free(skey);

    if (scert2)
        X509_free(scert2);
    if (skey)
        EVP_PKEY_free(skey2);

    if (in)
        BIO_free(in);
    if (b64)
        BIO_free(b64);
    if (out)
        BIO_free(out);
    if (tbio)
        BIO_free(tbio);

    return retStr;

}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值