1. 程式人生 > >Objective-C CMS簽名的實現

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; }