Objective-C CMS签名的实现

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/rdsuncn1977/article/details/54708807

通过私钥和证书封装成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;

}

猜你喜欢

转载自blog.csdn.net/rdsuncn1977/article/details/54708807
今日推荐