x509证书 xelios
2014-07-08 14:42:08 u013030990 阅读数 2832

         利用openssl进行X509证书解析

-(NSString *)certifacateConvertToX509withoption:(NSInteger)Number andSerialNumber:(NSString *)serialNumber

{

    //DER证书缓冲区数组

    unsigned char usrCertificate[4096];

    //证书长度

    unsigned long usrCertificateLen;

    //X509证书结构体,保存证书

    X509 *usrCert;

    const unsigned char *pTmp = NULL;

    

    //根据证书序列号判断转换哪一张证书 serialNumber如果为空 正常执行

    if(serialNumber != NULL)

    {

    NSString *cerInfo =  [SFHFKeychainUtils getPasswordForUsername:@"key" andServiceName:@"cn.com.szca.tp" error:nil];

    if(cerInfo == NULL)

    {

        NSLog(@"证书文件为空,请重新申请证书");

        return NO;

    }

    NSData* jsondata=[cerInfo dataUsingEncoding:NSUTF8StringEncoding];

    NSDictionary* json = [NSJSONSerialization JSONObjectWithData:jsondata options:kNilOptions error:nil];

    NSArray *jsonarr = [json objectForKey:@"key"];

    NSMutableDictionary *jsonDic = [[NSMutableDictionary alloc]init];

    for(int i = 0; i < [jsonarr count]; i++)

    {

        NSDictionary *dictionary = [jsonarr objectAtIndex:i];

        jsonDic =[dictionary objectForKey:serialNumber];

        if(jsonDic != NULL)

        {

            break;

        }

    }

    if(jsonDic == NULL)

    {

        NSLog(@"序列号错误");

        return NO;

    }

    NSString *cerstr = [jsonDic objectForKey:@"certificate"];

    NSMutableData *decoData = [[NSMutableData alloc]initWithData:[self dataWithBase64EncodedString:cerstr]];

    [decoData writeToFile:RSACertificateFile atomically:YES];

    }

    

    //读取证书

FILE *fp=fopen([RSACertificateFile cStringUsingEncoding:NSASCIIStringEncoding],"rb");

if(fp==NULL)

{

printf("open file err\n");

        _verifyErrorMessge = @"证书文件打开失败";

return nil;

}

usrCertificateLen = fread(usrCertificate,1,4096,fp);

fclose(fp);

    

pTmp=usrCertificate;

    // 判断是否为DER格式的数字证书

usrCert = d2i_X509(NULL,&pTmp,usrCertificateLen);

if(usrCert==NULL)

{

BIO *b;

        // 判断是否为PEM格式的数字证书

        b=BIO_new_file([RSACertificateFile cStringUsingEncoding:NSASCIIStringEncoding],"r");

        usrCert=PEM_read_bio_X509(b,NULL,NULL,NULL);

        //X509_print(b, usrCert);

        BIO_free(b);

        if(usrCert==NULL)

        {

            _verifyErrorMessge = @"证书解析失败";

            return nil;

        }

}

    //X509结构写入文件

    FILE *filex509;

    filex509 = fopen([RSAX509File cStringUsingEncoding:NSASCIIStringEncoding],"w");

    PEM_write_X509(filex509, usrCert);

    fclose(filex509);

    

    //X509转化为RSA结构

    EVP_PKEY *pkey = X509_get_pubkey(usrCert);

rsa_verify = pkey->pkey.rsa;

    if(rsa_verify == NULL)

    {

        _verifyErrorMessge = @"证书解析失败";

    }

    _deatailInfor = [self tGetX509Info:usrCert withoption:Number];

    return _deatailInfor;

}

服务器下发的证书是der格式的证书,存入keychain中,如    NSString *cerInfo =  [SFHFKeychainUtils getPasswordForUsername:@"key" andServiceName:@"cn.com.szca.tp" error:nil]; 从keychain里面取der证书,解析成x509格式。

入参为证书序列号,如果keychain中只有单证书,证书序列号为空不影响程序,多证书状况下要使用序列号来匹配

RSAX509File是存放的路径;Number是自定义获取证书的字段,可以删除,不使用,_deatailInfor = [self tGetX509Info:usrCert withoption:Number]; 是解析X509证书的各个条目,上一篇博客有详细代码。

2018-05-11 17:37:00 weixin_34361881 阅读数 42

1. 第一步先去认真看下下边这两个连接,了解一下这个x509证书解析到底是个什么玩意

http://www.360doc.com/content/16/0407/16/3242454_548621325.shtml

了解之后大约需要做三步:第一步导入openssl库,如何导入自行百度,注意路径问题,

3376343-823138c48a8c996d.png
路径如图,根据自己实际项目修改

第二部:将证书导入结构体


3376343-a5a6e77a95865591.png

第三部就是证书解析:我这只解析了证书版本,证书序列号(sn),证书颁发者名字(issuer_name),证书颁发者序列号(issuer_sn)


3376343-f4feb29ec5bbe2c3.png

/** 获取SN */

-(NSString*)get_SN:(X509* )m_px{


 NSString* str_SN=@"";


    ASN1_INTEGER*serial =X509_get_serialNumber(m_px);


    //打印证书序列号


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

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

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


    {


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


        [strappendString:[NSStringstringWithFormat:@"%02x",serial->data[i]]];


    }




    //小写转大写

   // str_SN=str.uppercaseString;

    //奇数补0操作

    if(str_SN.length%2==1) {

        str_SN=[NSStringstringWithFormat:@"0%@",str_SN];

    }

    returnstr_SN;

}

/** 获取版本号 */

-(NSString*)get_version:(X509* )m_px{

    NSString* str_version=@"";

    NSIntegerver =X509_get_version(m_px);

//    NSLog(@"ver=%zi",ver);

    switch(ver)

    {

        case0:    //V1

            //...

            str_version=@"V1";

            break;

        case1:    //V2

            //...

            str_version=@"V2";

            break;

        case2:    //V3

            //...

            str_version=@"V3";

            break;

        default:

            //Error!

            break;

    }

    returnstr_version;

}

/** 获取issuer 以及 issuer_sn */

-(NSDictionary*)get_issuer_nameAnd_issuer_sn:(X509* )m_px{

    NSMutableDictionary * dict_issuer =[[NSMutableDictionary alloc]init];

    [dict_issuersetObject:@""forKey:@"issuer_name"];

    [dict_issuersetObject:@""forKey:@"issuer_sn"];

    //解析

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

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

//    NSMutableString * _serialNumber = [[NSMutableString alloc]init];

//    NSMutableString * _allCertsList = [[NSMutableString alloc]init];

    inti;

    intentriesNum;

    X509_NAME_ENTRY*name_entry;

    longNid;

    unsignedcharmsginfo[1024];

    intmsginfoLen;

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

    X509_NAME* issuer =X509_get_issuer_name(m_px);

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

                [dict_issuersetObject:[NSStringstringWithFormat:@"%s",msginfo]forKey:@"issuer_name"];

                break;

            case NID_pkcs9_emailAddress://Mail

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

                break;

            case NID_serialNumber://issuerSN

                //NSLog(@"issuer 's SN:%zi\n",Nid);

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

                [dict_issuersetObject:[NSStringstringWithFormat:@"%s",msginfo]forKey:@"issuer_sn"];

                break;

            default:

                break;

        }

    }

    //[_allCertsList appendString:certInfo];

    //[_allCertsList appendString:@"|"];

    returndict_issuer;

}



/**************************************************************************************/

/**************************************************************************************/

/**************************************************************************************/

/**************************************************************************************/

改:下边为解析源码,需要的自行复制:

/**************************************************************************************/

//

//  JJDEAnalyticalCert.m

//  EIDprepareForSDK

//

//  Created by yyb on 2018/5/2.

//  Copyright © 2018年 yyb. All rights reserved.

//

#import "JJDEAnalyticalCert.h"

#import"x509.h"

#import "x509v3.h"

#import "x509_vfy.h"

#import "JJDEGetCertInfo.h"

@interface JJDEAnalyticalCert()

@property (nonatomic,copy) Id_Block sendBlock;

@end

@implementationJJDEAnalyticalCert

//全局变量

static JJDEAnalyticalCert * _instance = nil;

//单例方法

+(instancetype)shareBlueTooth{

    return[[selfalloc]init];

}

////alloc会调用allocWithZone:

+(instancetype)allocWithZone:(struct_NSZone*)zone{

    //只进行一次

    staticdispatch_once_tonceToken;

    dispatch_once(&onceToken, ^{

        _instance= [superallocWithZone:zone];


    });

    return _instance;

}

//初始化方法

- (instancetype)init{

    // 只进行一次

    staticdispatch_once_tonceToken;

    dispatch_once(&onceToken, ^{

        _instance= [superinit];

        ;


    });


    return _instance;

}

-(void)deCardSendInstructions_AnalyticalCertWithString:(NSString*)strName andObj:(NSDictionary*)objc andCompletion:(Id_Block)comBlock{


    JJDEGetCertInfo * degetCertInfo = [JJDEGetCertInfo shareBlueTooth];

    if(degetCertInfo.data_certInfo.length<=0) {

        return;

    }


    NSString * str_data=[JJBluetoothTools convertDataToHexStr:degetCertInfo.data_certInfo];//@"30820316308202BBA00302010202081000000000235751300C06082A811CCF550183750500303E310B3009060355040A0C0247413111300F06035504030C08654944204D494332310F300D06035504050C06303232303132310B300906035504061302434E301E170D3136303931323037333831305A170D3139303931323037333831305A306D314D304B06035504030C44414145397739444A62574C6D6248637744796278623039335446364549436D4A624F41546B5A50794A51414A6B78325644706154655A6351544E7942514F57657645303D310B300906035504060C02434E310F300D060355040A0C063331303030303059301306072A8648CE3D020106082A811CCF5501822D0342000413B29FD275B4A70FE70855280F6CE63CE9BAEC93097A7A71160B9AB5EF357585E71FAFDACD61593912877BA609A9A218ECE1279CA98451787EEA75C8DF9BF1CEA38201703082016C302B0603551D0E0424042204209FA4361184D90E43424EDB2A563EB2739CBAD0319F4367469DD64D21632A39E7302F0603551D23042830268024302280202F4E21716079671BFF36A480BA670C66D1F8D9396F1EAA67F4EC77E8F9D1FCB3300C0603551D1304053003010100300B0603551D0F0404030206C0301D0603551D250416301406082B0601050507030206082B0601050507030430360603551D20042F302D302B06082A811C86EF580202301F301D06082B060105050702011611687474703A2F2F6569642E636E2F637073301106096086480186F8420101040403020780303E06082B0601050507010104323030302E06082B060105050730028622687474703A2F2F63657274732E6569642E636E2F6549444D4943526F6F742E63657230470603551D1F0440303E303CA03AA0388636687474703A2F2F63726C2E6569642E636E2F646F776E6C6F61642F534D325F6549442532304D4943325F67726F7570305F622E63726C300C06082A811CCF550183750500034700304402201F6EFA9BAC64B381DEE7F49112CB6BB04BA9114708D4EFA63F45EC8FF945947C02204C3F481BCB8C6A0ADFF53440B83D35E23EB4BF041782D027F52B3DDF69CE5FE9";

    NSData* lpCertData =[JJBluetoothToolshexToBytes:str_data];

    Byte* bytes_lpCertData =(Byte*)[lpCertDatabytes];//031A

    X509* m_px=d2i_X509(NULL, (unsignedcharconst**)&bytes_lpCertData,794);







   //获取版本号

    //NSString * string_version = [self get_version:m_px];

    //获取SN

    NSString* string_SN =[selfget_SN:m_px];

    //获取颁发者名字和颁发者序列号

    NSDictionary* dict_issuer = [selfget_issuer_nameAnd_issuer_sn:m_px];

    //NSLog(@"%@",dict_issuer);

    //颁发者名字

    NSString* string_issuer_name=dict_issuer[@"issuer_name"];

    //颁发者序列号

    NSString* string_issuer_sn=dict_issuer[@"issuer_sn"];


    if(string_SN.length>0&& string_issuer_name.length>0&& string_issuer_sn.length>0) {

        self.string_SN=string_SN;

        self.string_issuer_name=string_issuer_name;

        self.string_issuer_sn=string_issuer_sn;

        if(comBlock) {

            comBlock(@{@"status":@"1",@"msg":@"证书解析成功"});

        }

    }else{

        self.string_SN=nil;

        self.string_issuer_name=nil;

        self.string_issuer_sn=nil;

        if(comBlock) {

            comBlock(@{@"status":@"0",@"msg":@"证书解析失败"});

        }

    }


}

/** 获取SN */

-(NSString*)get_SN:(X509* )m_px{


 NSString* str_SN=@"";


    ASN1_INTEGER*serial =X509_get_serialNumber(m_px);


    //打印证书序列号


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

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

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


    {


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


        [strappendString:[NSStringstringWithFormat:@"%02x",serial->data[i]]];


    }





    //小写转大写

    //str_SN=str.uppercaseString;

    //奇数补0操作

    if(str_SN.length%2==1) {

        str_SN=[NSStringstringWithFormat:@"0%@",str_SN];

    }

    returnstr_SN;

}

/** 获取版本号 */

-(NSString*)get_version:(X509* )m_px{

    NSString* str_version=@"";


    NSIntegerver =X509_get_version(m_px);

//    NSLog(@"ver=%zi",ver);

    switch(ver)

    {

        case0:    //V1

            //...

            str_version=@"V1";

            break;

        case1:    //V2

            //...

            str_version=@"V2";

            break;

        case2:    //V3

            //...

            str_version=@"V3";

            break;

        default:

            //Error!

            break;

    }


    returnstr_version;

}

/** 获取issuer 以及 issuer_sn */

-(NSDictionary*)get_issuer_nameAnd_issuer_sn:(X509* )m_px{

    NSMutableDictionary * dict_issuer =[[NSMutableDictionary alloc]init];

    [dict_issuersetObject:@""forKey:@"issuer_name"];

    [dict_issuersetObject:@""forKey:@"issuer_sn"];

    //解析

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

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

//    NSMutableString * _serialNumber = [[NSMutableString alloc]init];

//    NSMutableString * _allCertsList = [[NSMutableString alloc]init];

    inti;

    intentriesNum;

    X509_NAME_ENTRY*name_entry;

    longNid;

    unsignedcharmsginfo[1024];

    intmsginfoLen;

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

    X509_NAME* issuer =X509_get_issuer_name(m_px);

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

                [dict_issuersetObject:[NSStringstringWithFormat:@"%s",msginfo]forKey:@"issuer_name"];

                break;

            case NID_pkcs9_emailAddress://Mail

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

                break;

            case NID_serialNumber://issuerSN

                //NSLog(@"issuer 's SN:%zi\n",Nid);

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

                [dict_issuersetObject:[NSStringstringWithFormat:@"%s",msginfo]forKey:@"issuer_sn"];

                break;

            default:

                break;

        }

    }

    //[_allCertsList appendString:certInfo];

    //[_allCertsList appendString:@"|"];


    returndict_issuer;

}

@end

2014-07-08 14:30:08 u013030990 阅读数 3709

       在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<entriesNum;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<entriesNum;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判断中的代码是无效的,本来这里是解决中文字符的编码问题,但是

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

2017-01-15 15:26:00 weixin_34235135 阅读数 28

在解析证书信息之前,需要将证书转换为X509结构体。以下代码中<code>cert</code>为X509证书结构体

<h4>一、解析证书序列号</h4>

ASN1_INTEGER *serial = X509_get_serialNumber(cert);
BIGNUM *btn = ASN1_INTEGER_to_BN(serial, NULL);
char *res = BN_bn2hex(btn);
NSString *serialStr = [NSString stringWithUTF8String:res];
NSLog(@"序列号:%@",serialStr);

<h4>二、解析证书拥有者信息(用户名)</h4>

char szOutCN[256]={0};
X509_NAME *name = NULL;
name = cert->cert_info->subject;      
X509_NAME_get_text_by_NID(name,NID_commonName,szOutCN,256)
NSString *nameStr = [NSString stringWithUTF8String:szOutCN];
NSLog(@"用户名:%@",nameStr);

<h4>三、解析证书颁发机构</h4>

X509_NAME_ENTRY *name_entry;
long Nid;
unsigned char msginfo[1024];
int msginfoLen;
        
NSMutableString *issuerInfo = [[NSMutableString alloc] init];
NSMutableString *certCN = [[NSMutableString alloc] init];
        
X509_NAME *issuer = X509_get_issuer_name(cert);
int entriesNum = sk_X509_NAME_ENTRY_num(issuer->entries);
for (int i = 0; i < entriesNum; i++) {
    name_entry = sk_X509_NAME_ENTRY_value(issuer->entries, i);
            
    Nid = OBJ_obj2nid(name_entry->object);
    msginfoLen = name_entry->value->length;
    memcpy(msginfo,name_entry->value->data,msginfoLen);
    msginfo[msginfoLen]='\0';
            
    switch(Nid)
    {
        case NID_countryName://国家C
                    [issuerInfo appendString:[NSString stringWithFormat:@"C=%s,",msginfo]];
                    [certCN appendString:[NSString stringWithFormat:@"C=%s",msginfo]];
                    break;
                    
        case NID_stateOrProvinceName://省ST
                    [issuerInfo appendString:[NSString stringWithFormat:@"ST=%s,",msginfo]];
                    break;
                    
        case NID_localityName://地区L
                    [issuerInfo appendString:[NSString stringWithFormat:@"L=%s,",msginfo]];
                    break;
                    
        case NID_organizationName://组织O=
                    [issuerInfo appendString:[NSString stringWithFormat:@"O=%s,",msginfo]];
                    break;
                    
        case NID_organizationalUnitName://单位OU
                    [issuerInfo appendString:[NSString stringWithFormat:@"OU=%s,",msginfo]];
                    break;
                    
        case NID_commonName://通用名CN
                    [issuerInfo appendString:[NSString stringWithFormat:@"CN=%s",msginfo]];
                    break;
                    
        case NID_pkcs9_emailAddress://Mail
                    break;
                    
            }
}

NSLog(@"颁发机构:%@",issuerInfo);

<h4>四、解析证书密钥算法</h4>

EVP_PKEY *pk = NULL;
pk = X509_get_pubkey(cert);
NSString *pulType;
        
if (EVP_PKEY_RSA == pk->type) {
    pulType = @"RSA";
} else if (EVP_PKEY_EC == pk->type) {
    pulType = @"EC";
} else if (EVP_PKEY_DSA == pk->type) {
    pulType = @"DSA";
} else if (EVP_PKEY_DH == pk->type) {
    pulType = @"DH";
} else {
    pulType = @"UNKNOWN";
}

NSLog(@"密钥算法:%@",pulType);

<h4>五、解析证书颁发时间和过期时间</h4>

解析办法时间需要一个工具方法,因为直接获取时间为格林威治时间。需要把它转化成秒数然后再转化为本地时间。

<b>将格林威治时间转换成秒数的方法</b>
原方法地址:http://stackoverflow.com/questions/10975542/asn1-time-to-time-t-conversion

- (time_t)skf_ext_ASN1_GetTimeT:(ASN1_TIME *)time {
    struct tm t;
    const char* str = (const char*) time->data;
    size_t i = 0;
    
    memset(&t, 0, sizeof(t));
    
    if (time->type == V_ASN1_UTCTIME) {/* two digit year */
        t.tm_year = (str[i++] - '0') * 10;
        t.tm_year += (str[i++] - '0');
        if (t.tm_year < 70)
            t.tm_year += 100;
    } else if (time->type == V_ASN1_GENERALIZEDTIME) {/* four digit year */
        t.tm_year = (str[i++] - '0') * 1000;
        t.tm_year+= (str[i++] - '0') * 100;
        t.tm_year+= (str[i++] - '0') * 10;
        t.tm_year+= (str[i++] - '0');
        t.tm_year -= 1900;
    }
    t.tm_mon  = (str[i++] - '0') * 10;
    t.tm_mon += (str[i++] - '0') - 1; // -1 since January is 0 not 1.
    t.tm_mday = (str[i++] - '0') * 10;
    t.tm_mday+= (str[i++] - '0');
    t.tm_hour = (str[i++] - '0') * 10;
    t.tm_hour+= (str[i++] - '0');
    t.tm_min  = (str[i++] - '0') * 10;
    t.tm_min += (str[i++] - '0');
    t.tm_sec  = (str[i++] - '0') * 10;
    t.tm_sec += (str[i++] - '0');
    
    /* Note: we did not adjust the time based on time zone information */
    return mktime(&t);
}

<b>解析时间方法</b>


ASN1_TIME *start = NULL;
ASN1_TIME *end = NULL;
time_t ttStart = {0};
time_t ttEnd = {0};
        
// 颁发时间
start = X509_get_notBefore(cert);
ttStart = [self skf_ext_ASN1_GetTimeT:start];
// 格林威治时间与北京时间相差八小时,所以加八小时。
ttStart = ttStart + 8 * 60 * 60; 
NSDate *startDate = [NSDate dateWithTimeIntervalSince1970:ttStart];
NSString *startDateStr = [self.dateFormatter stringFromDate:startDate];
NSLog(@"颁发时间:%@",startDateStr);

// 过期时间
end = X509_get_notAfter(cert);
ttEnd = [self skf_ext_ASN1_GetTimeT:end];
ttEnd = ttEnd + 8 * 60 * 60;
NSDate *endDate = [NSDate dateWithTimeIntervalSince1970:ttEnd];
NSString *endDateStr = [self.dateFormatter stringFromDate:endDate];
NSLog(@"过期时间:%@",endDateStr);

<b><code>self.dateFormatter</code>懒加载方法</b>

- (NSDateFormatter *)dateFormatter
{
    if (!_dateFormatter) {
        _dateFormatter = [[NSDateFormatter alloc] init];
        NSTimeZone *zone = [NSTimeZone localTimeZone];
        [_dateFormatter setTimeZone:zone];
        [_dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
    }
    return _dateFormatter;
}

全文完

2018-05-20 11:38:25 a133900029 阅读数 47

iOS 证书

阅读数 100

iOS 证书

阅读数 352

IOS 证书

阅读数 664

1.下载2.下载就ok了。

博文 来自: zhengxf_2012

iOS 证书

阅读数 156

iOS 证书

阅读数 180

没有更多推荐了,返回首页