在解析證書信息之前颈嚼,需要將證書轉(zhuǎn)換為X509結(jié)構(gòu)體。以下代碼中<code>cert</code>為X509證書結(jié)構(gòu)體
<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>三、解析證書頒發(fā)機(jī)構(gòu)</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://地區(qū)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(@"頒發(fā)機(jī)構(gòu):%@",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>五浦楣、解析證書頒發(fā)時間和過期時間</h4>
解析辦法時間需要一個工具方法,因?yàn)橹苯荧@取時間為格林威治時間咪辱。需要把它轉(zhuǎn)化成秒數(shù)然后再轉(zhuǎn)化為本地時間振劳。
<b>將格林威治時間轉(zhuǎn)換成秒數(shù)的方法</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};
// 頒發(fā)時間
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(@"頒發(fā)時間:%@",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;
}
全文完