iOS 使用Openssl解析X509证书

       在iOS中使用Openssl解析X509证书,加入openssl的库文件,头文件,传入X509证书结构,代码如下:

-(NSString *)tGetX509Info:(X509 *)cerfilepath withoption:(NSInteger)Number

{

NSMutableString *certInfo = [[NSMutableString alloc]init];

    NSMutableString *certCN = [[NSMutableString alloc]init];

    _serialNumber = [[NSMutableString alloc]init];

    _allCertsList = [[NSMutableString alloc]init];

    

    X509 *x509Cert = cerfilepath; //X509证书结构体

unsigned char *pTmp = NULL;

X509_NAME *issuer = NULL; //X509_NAME结构体,保存证书颁发者信息

X509_NAME *subject = NULL; //X509_NAME结构体,保存证书拥有者信息

int i;

int entriesNum;

X509_NAME_ENTRY *name_entry;

ASN1_INTEGER *Serial = NULL; //保存证书序列号

long Nid;

ASN1_TIME *time; //保存证书有效期时间

EVP_PKEY *pubKey; //保存证书公钥

long Version; //保存证书版本

unsigned char derpubkey[1024];

//int derpubkeyLen;

unsigned char msginfo[1024];

int msginfoLen;

    //打印整个X509结构信息

    //int ret;

    BIO *b;

    b= BIO_new ( BIO_s_file ());

    BIO_set_fp (b, stdout , BIO_NOCLOSE );

    // 把 X509 结构打印输出到文件 BIO

    //X509_print (b,x509Cert);

    // 释放流

    BIO_free (b);

    

Version = X509_get_version(x509Cert);                                              //获取证书版本

//printf("X509 Version:%ld\n",Version);

    

//获取证书颁发者信息,X509_NAME结构体保存了多项信息,包括国家、组织、部门、通用名、mail等。

issuer = X509_get_issuer_name(x509Cert);

    

entriesNum = sk_X509_NAME_ENTRY_num(issuer->entries);            //获取X509_NAME条目个数

//循环读取各条目信息

for(i=0;i

{

//获取第I个条目值

name_entry = sk_X509_NAME_ENTRY_value(issuer->entries,i);

//获取对象ID

Nid = OBJ_obj2nid(name_entry->object);

        msginfoLen=name_entry->value->length;

        memcpy(msginfo,name_entry->value->data,msginfoLen);

        msginfo[msginfoLen]='\0';

//根据NID打印出信息

      //  NSLog(@"issuer type is %d",name_entry->value->type);

switch(Nid)

{

            case NID_countryName://国家C

                //printf("issuer 's C:%s\n",msginfo);

                [certInfo appendString:[NSString stringWithFormat:@"C=%s,",msginfo]];

                [certCN appendString:[NSString stringWithFormat:@"C=%s",msginfo]];

                break;

            case NID_stateOrProvinceName://省ST

                //printf("issuer 's ST:%s\n",msginfo);

                [certInfo appendString:[NSString stringWithFormat:@"ST=%s,",msginfo]];

                break;

            case NID_localityName://地区L

                //printf("issuer 's L:%s\n",msginfo);

                [certInfo appendString:[NSString stringWithFormat:@"L=%s,",msginfo]];

                break;

            case NID_organizationName://组织O

                //printf("issuer 's O:%s\n",msginfo);

                [certInfo appendString:[NSString stringWithFormat:@"O=%s,",msginfo]];

                break;

            case NID_organizationalUnitName://单位OU

                //printf("issuer 's OU:%s\n",msginfo);

                [certInfo appendString:[NSString stringWithFormat:@"OU=%s,",msginfo]];

                break;

            case NID_commonName://通用名CN

                //printf("issuer 's CN:%s\n",msginfo);

                [certInfo appendString:[NSString stringWithFormat:@"CN=%s",msginfo]];

                break;

            case NID_pkcs9_emailAddress://Mail

                //printf("issuer 's emailAddress:%s\n",msginfo);

                break;

}

}

    [_allCertsList appendString:certInfo];

    [_allCertsList appendString:@"|"];

    

Serial = X509_get_serialNumber(x509Cert);                    //获取证书序列号

//打印证书序列号

//printf("serialNumber is: \n");

for(i = 0; i < Serial->length; i++)

{

//printf("%02x", Serial->data[i]);

        [_serialNumber appendString:[NSString stringWithFormat:@"%02x",Serial->data[i]]];

}

    

    [_allCertsList appendString:_serialNumber];

    

    

subject = X509_get_subject_name(x509Cert);            //获取证书主题信息

    NSMutableString *subjectstring = [[NSMutableString alloc]init];

    

    int countsubject = X509_NAME_entry_count(subject);

    X509_NAME_ENTRY  *subjectEntry = X509_NAME_get_entry(subject,2);

    X509_NAME_ENTRY_get_object(subjectEntry);

    X509_NAME_ENTRY_get_data(subjectEntry);

    NSString  *subjectstr = [NSString stringWithUTF8String:X509_NAME_ENTRY_get_data(subjectEntry)->data];

    NSLog(@"final test %@",subjectstr);

    

    entriesNum = sk_X509_NAME_ENTRY_num(subject->entries);

    //循环读取个条目信息

    for(i=0;i

    {

        //获取第I个条目值

        name_entry = sk_X509_NAME_ENTRY_value(subject->entries,i);

        Nid = OBJ_obj2nid(name_entry->object);

        //判断条目编码的类型

        NSLog(@" type is  %d",name_entry->value->type);

        

        if(name_entry->value->type==V_ASN1_BMPSTRING)//把UTF8编码数据转化成可见字符

        {

            //ASN1_STRING_to_UTF8(mesre,name_entry->value);

            msginfoLen=name_entry->value->length;

            memcpy(msginfo,name_entry->value->data,msginfoLen);

            msginfo[msginfoLen]='\0';

            NSString *temptring = [NSString stringWithFormat:@"C=%s,",msginfo];

            //tempstr = [self EncodeUTF8Str:temptring];

//            msginfoLen =UTF8_getc(name_entry->value->data, 2*name_entry->value->length, &rv);

//            //msginfoLen =UTF8_putc(name_entry->value->data, name_entry->value->length, rv);

//            //memcpy(msginfo,name_entry->value->data,msginfoLen);

//            msginfo[msginfoLen]='\0';

//            NSData *tempdata = [temptring dataUsingEncoding:NSUTF8StringEncoding];

//            NSStringEncoding gbkEncoding =CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingGB_18030_2000);

//            NSString*pageSource = [[NSString alloc] initWithData:tempdata encoding:gbkEncoding];

            NSString*pageSource = [self encodeToPercentEscapeString:temptring];

            NSString *dataGBK = [pageSource stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];

            tempstr = dataGBK;

           

        }

        else

        {

            tempstr = [NSString stringWithFormat:@"C=%s,",msginfo];

            msginfoLen=name_entry->value->length;

            memcpy(msginfo,name_entry->value->data,msginfoLen);

            msginfo[msginfoLen]='\0';

        }

        switch(Nid)

        {

            case NID_countryName://国家C

                //printf("issuer 's C:%s\n",msginfo);

                [subjectstring appendString:[NSString stringWithFormat:@"C=%s,",msginfo]];

                break;

            case NID_stateOrProvinceName://省ST

                //printf("issuer 's ST:%s\n",msginfo);

                //[subjectstring appendString:[NSString stringWithFormat:@"ST=%s,",msginfo]];

                [subjectstring appendString:tempstr];

                break;

            case NID_localityName://地区L

                //printf("issuer 's L:%s\n",msginfo);

                [subjectstring appendString:[NSString stringWithFormat:@"L=%s,",msginfo]];

                break;

            case NID_organizationName://组织O

                //printf("issuer 's O:%s\n",msginfo);

                [subjectstring appendString:[NSString stringWithFormat:@"O=%s,",msginfo]];

                break;

            case NID_organizationalUnitName://单位OU

                //printf("issuer 's OU:%s\n",msginfo);

                [subjectstring appendString:[NSString stringWithFormat:@"OU=%s,",msginfo]];

                break;

            case NID_commonName://通用名CNx

                //printf("issuer 's CN:%s\n",msginfo);

                [subjectstring appendString:[NSString stringWithFormat:@"CN=%s",msginfo]];

                break;

            case NID_pkcs9_emailAddress://Mail

                //printf("issuer 's emailAddress:%s\n",msginfo);

                break;

        }//end switch

    }

    

time = X509_get_notBefore(x509Cert);                      //获取证书生效日期

//printf("Cert notBefore:%s\n",time->data);

    NSString *notBefore = [NSString stringWithFormat:@"%s",time->data];

time = X509_get_notAfter(x509Cert);                        //获取证书过期日期

//printf("Cert notAfter:%s\n",time->data);

    NSString *notAfter = [NSString stringWithFormat:@"%s",time->data];

pubKey = X509_get_pubkey(x509Cert);                    //获取证书公钥

pTmp=derpubkey;


X509_free(x509Cert);

    NSMutableString *finaldetail = [[NSMutableString alloc]init];

    NSString *detaiInfo =  [[NSString  alloc]init];

    NSString *cerEntity = [[NSString alloc]initWithContentsOfFile:RSAX509File encoding:NSUTF8StringEncoding error:nil];

    

    NSMutableString *notAftertime = [[NSMutableString alloc]initWithString:@"20"];

    NSRange range = NSMakeRange (19, 1);

    

    switch (Number) {

        case 1:

            //[finaldetail appendString:@"Version is "];

            detaiInfo =  [NSString stringWithFormat:@"%ld",Version];

            [finaldetail appendString:detaiInfo];

            break;

        case 2:

            detaiInfo =  _serialNumber;

            [finaldetail appendString:detaiInfo];

            break;

        case 3:

            //[finaldetail appendString:@"Issuer is "];

            detaiInfo =  certInfo;

            [finaldetail appendString:detaiInfo];

            break;

        case 4:

            //[finaldetail appendString:@"NotBefore "];

            [notAftertime appendString:notBefore];

            [notAftertime insertString:@"-" atIndex:4];

            [notAftertime insertString:@"-" atIndex:7];

            [notAftertime insertString:@" " atIndex:10];

            [notAftertime insertString:@":" atIndex:13];

            [notAftertime insertString:@":" atIndex:16];

            [notAftertime replaceCharactersInRange:range withString:@""];

            [finaldetail appendString:notAftertime];

            break;

        case 5:

            //[finaldetail appendString:@"NotAfter "];

            [notAftertime appendString:notAfter];

            [notAftertime insertString:@"-" atIndex:4];

            [notAftertime insertString:@"-" atIndex:7];

            [notAftertime insertString:@" " atIndex:10];

            [notAftertime insertString:@":" atIndex:13];

            [notAftertime insertString:@":" atIndex:16];

            [notAftertime replaceCharactersInRange:range withString:@""];

            [finaldetail appendString:notAftertime];

            break;

        case 6:

            //[finaldetail appendString:@"Cer Entity is \n"];

            [finaldetail appendString:cerEntity];

            break;

        case 7:

            [finaldetail appendString:certCN];

            break;

        case 8:

            [finaldetail appendString:subjectstring];

            break;

        default:

            break;

    }

return finaldetail;

}



解析X509主题信息中,如果主题有中文,会出现乱码,

把UTF8编码数据转化成可见字符,这个if判断中的代码是无效的,本来这里是解决中文字符的编码问题,但是

至今这个问题还没解决,如有方法,请大家告知,不胜感激!

你可能感兴趣的:(iOS技术分享)