Objective-C CMS簽名的實現
阿新 • • 發佈:2018-11-05
通過私鑰和證書封裝成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;
}