获取证书数据获取
+(NSDictionary *)getCertInfoWithCerData:(NSData *)certData json:(NSString *)json{
if (!certData||certData.length < 10) {
return nil;
}
NSMutableDictionary * cerInfo = [NSMutableDictionary dictionary];
SecCertificateRef cert = SecCertificateCreateWithData(NULL, (CFDataRef)certData);
const unsigned char *certificateDataBytes = (const unsigned char *)[certData bytes];
X509 *certificateX509 = d2i_X509(NULL, &certificateDataBytes, [certData length]);
if (certificateX509 == NULL) {
return nil;
}
ASN1_INTEGER *serial = X509_get_serialNumber(certificateX509);
BIGNUM *btn = ASN1_INTEGER_to_BN(serial, NULL);
char *res = BN_bn2hex(btn);
printX509(certificateX509);
NSString *serialStr = [NSString stringWithUTF8String:res];
NSLog(@"序列号:%@",serialStr);
cerInfo[@"codeSignTime"] = [self getSignTimeStringWithJson:json];
cerInfo[@"name"] = [NSString stringWithFormat:@"%@",@"SM3WITHSM2"];
cerInfo[@"OID"] = @"1.2.156.10197.1.501";
cerInfo[@"decodeName"] = @"X.509";
cerInfo[@"serialNumber"] = [NSString stringFromHexString:serialStr];
id publicKey11 = nil;
SecCertificateRef certificate;
certificate = cert;
SecCertificateRef certificates[1];
CFArrayRef tempCertificates = nil;
SecPolicyRef policy = nil;
SecTrustRef trust = nil;
SecTrustResultType result;
if (certificate != NULL) {
certificates[0] = certificate;
tempCertificates = CFArrayCreate(NULL, (const void **)certificates, 1, NULL);
policy = SecPolicyCreateBasicX509();
SecTrustCreateWithCertificates(tempCertificates, policy, &trust);
SecTrustEvaluate(trust, &result);
// 获得公钥对象
publicKey11 = (__bridge_transfer id)SecTrustCopyPublicKey(trust);
}
if (CFArrayGetCount(tempCertificates) > 0) {
CFDictionaryRef identityDict = CFArrayGetValueAtIndex(tempCertificates, 0);
NSDictionary * certInfo = (__bridge_transfer NSDictionary *)identityDict;
NSString * userId = [self getUintNameWithCertInfo:certInfo];
NSLog(@"certUserID:%@",userId);
cerInfo[@"userId"] = userId;
cerInfo[@"hostName"] = userId;
}
NSDate * signStartDate = CertificateSignBeginDate(certificateX509);
cerInfo[@"signNameStartTime"] = [NSString stringWithFormat:@"%@ +8'00'",[self localStringFromUTCDate:signStartDate]];
NSDate * effectiveDate = CertificateGetExpiryDate(certificateX509);
NSLog(@"Time:%@",effectiveDate);
cerInfo[@"signNameEndTime"] = [NSString stringWithFormat:@"%@ +8'00'",[self localStringFromUTCDate:effectiveDate]];
NSString * signName = CertificateGetIssuerName(certificateX509);
cerInfo[@"signName"] = signName;
NSLog(@"name:%@",signName);
int version = X509_get_version(certificateX509);
NSLog(@"版本号:%ld",version);
cerInfo[@"version"] = [NSString stringWithFormat:@"%ld",version + 1];
/// 获取公钥
NSData * keyData = [self getPublicKeyBitsFromKey:(__bridge SecKeyRef)(publicKey11)];
NSString * keyHasString = [self hexStringFromData:keyData];
NSLog(@"公钥key:%@",keyHasString);
cerInfo[@"publicKey"] = keyHasString;
NSString * dealKey = [keyHasString substringFromIndex:2];
cerInfo[@"px"] = [dealKey substringToIndex:64];
cerInfo[@"py"] = [dealKey substringFromIndex:64];
//颁发者信息
cerInfo[@"subObjectInfo"] = CertificateGetSubjectInfo(certificateX509);
//ca机构信息
cerInfo[@"CAInfoString"] = CertificateCertCaName(certificateX509);
NSLog(@"证书信息:%@",cerInfo);
return cerInfo;
}
///颁发结构名称
static NSString* CertificateGetIssuerName(X509*certificateX509)
{
NSString*issuer =nil;
if(certificateX509 !=NULL) {
X509_NAME*issuerX509Name =X509_get_issuer_name(certificateX509);
if(issuerX509Name !=NULL) {
charszOutCN[256]={0};
X509_NAME_get_text_by_NID(issuerX509Name,NID_commonName,szOutCN,256);
// NSString *nameStr = [NSString stringWithUTF8String:szOutCN];
int nid =OBJ_txt2nid("O");// organization
int index =X509_NAME_get_index_by_NID(issuerX509Name, nid, -1);
X509_NAME_ENTRY*issuerNameEntry =X509_NAME_get_entry(issuerX509Name, index);
if(issuerNameEntry) {
ASN1_STRING*issuerNameASN1 =X509_NAME_ENTRY_get_data(issuerNameEntry);
if(issuerNameASN1 !=NULL) {
unsigned char*issuerName =ASN1_STRING_data(issuerNameASN1);
issuer = [NSString stringWithUTF8String:(char*)issuerName];
}
}
int nid1 =OBJ_txt2nid("CN");// organization
int index1 =X509_NAME_get_index_by_NID(issuerX509Name, nid1, -1);
X509_NAME_ENTRY*issuerNameEntry11 =X509_NAME_get_entry(issuerX509Name, index1);
if(issuerNameEntry11) {
ASN1_STRING*issuerNameASN11 =X509_NAME_ENTRY_get_data(issuerNameEntry11);
if(issuerNameASN11 !=NULL) {
unsigned char*issuerName =ASN1_STRING_data(issuerNameASN11);
issuer = [NSString stringWithUTF8String:(char*)issuerName];
}
}
}
}
return issuer;
}
- ///CA机构信息
static NSString* CertificateCertCaName(X509*certificateX509)
{
// O 组织
// L地区
// ST省
// C国家
// OU单位
// CN通用名
NSMutableString *issuer = [NSMutableString new];
if(certificateX509 !=NULL) {
X509_NAME*issuerX509Name =X509_get_issuer_name(certificateX509);
if(issuerX509Name !=NULL) {
charszOutCN[256]={0};
X509_NAME_get_text_by_NID(issuerX509Name,NID_commonName,szOutCN,256);
// NSString *nameStr = [NSString stringWithUTF8String:szOutCN];
long nid =OBJ_txt2nid("C");// organization
int index =X509_NAME_get_index_by_NID(issuerX509Name, nid, -1);
X509_NAME_ENTRY*issuerNameEntry =X509_NAME_get_entry(issuerX509Name, index);
if(issuerNameEntry) {
ASN1_STRING*issuerNameASN1 =X509_NAME_ENTRY_get_data(issuerNameEntry);
if(issuerNameASN1 !=NULL) {
unsigned char*issuerName =ASN1_STRING_data(issuerNameASN1);
[issuer appendFormat:@"C=%@,",[NSString stringWithUTF8String:(char*)issuerName]];
}
}
long nid2 =OBJ_txt2nid("O");// organization
int index2 =X509_NAME_get_index_by_NID(issuerX509Name, nid2, -1);
X509_NAME_ENTRY*issuerNameEntry1 =X509_NAME_get_entry(issuerX509Name, index2);
if(issuerNameEntry1) {
ASN1_STRING*issuerNameASN11 =X509_NAME_ENTRY_get_data(issuerNameEntry1);
if(issuerNameASN11 !=NULL) {
unsigned char*issuerName2 =ASN1_STRING_data(issuerNameASN11);
[issuer appendFormat:@"O=%@,",[NSString stringWithUTF8String:(char*)issuerName2]];
}
}
int nid3 =OBJ_txt2nid("CN");// CN
int index3 =X509_NAME_get_index_by_NID(issuerX509Name, nid3, -1);
X509_NAME_ENTRY*issuerNameEntry3 =X509_NAME_get_entry(issuerX509Name, index3);
if(issuerNameEntry3) {
ASN1_STRING*issuerNameASN13 =X509_NAME_ENTRY_get_data(issuerNameEntry3);
if(issuerNameASN13 !=NULL) {
unsigned char*issuerName3 =ASN1_STRING_data(issuerNameASN13);
[issuer appendFormat:@"CN=%@",[NSString stringWithUTF8String:(char*)issuerName3]];
}
}
int nid4 =OBJ_txt2nid("title");// Title
int index4 =X509_NAME_get_index_by_NID(issuerX509Name, nid4, -1);
X509_NAME_ENTRY*issuerNameEntry4 =X509_NAME_get_entry(issuerX509Name, index4);
if(issuerNameEntry4) {
ASN1_STRING*issuerNameASN14 =X509_NAME_ENTRY_get_data(issuerNameEntry4);
if(issuerNameASN14 !=NULL) {
unsigned char*issuerName4 =ASN1_STRING_data(issuerNameASN14);
[issuer appendFormat:@"/title=%@",[NSString stringWithUTF8String:(char*)issuerName4]];
}
}
}
}
return issuer;
}
///主题信息获取
static NSString * CertificateGetSubjectInfo(X509*certificateX509){
NSMutableString * subObjectName = [NSMutableString string];
X509_NAME*name =X509_get_subject_name(certificateX509);
if(name !=NULL) {
charszOutCN[256]={0};
X509_NAME_get_text_by_NID(name,NID_commonName,szOutCN,256);
long nid =OBJ_txt2nid("ST");// organization
int index =X509_NAME_get_index_by_NID(name, nid, -1);
// int loc = X509_get_ext_by_NID(certificateX509, NID_crl_distribution_points, -1);
// X509_EXTENSION *ext = X509_get_ext(certificateX509, loc);
// ASN1_OCTET_STRING *os = X509_EXTENSION_get_data(ext);
// ASN1_STRING *s = X509_EXTENSION_get_data(ext);
// const unsigned char *data = ASN1_STRING_data(s);
// long length = ASN1_STRING_length(s);
// NSString *sss = [NSString stringWithUTF8String:(char*)data];
X509_NAME_ENTRY*subNameEntry =X509_NAME_get_entry(name, index);
if(subNameEntry) {
ASN1_STRING*subNameASN1 =X509_NAME_ENTRY_get_data(subNameEntry);
if(subNameASN1 !=NULL) {
unsigned char*issuerName =ASN1_STRING_data(subNameASN1);
[subObjectName appendFormat:@"ST=%@,",[NSString stringWithUTF8String:(char*)issuerName]];
}
}
long nidL =OBJ_txt2nid("L");// organization
int indexL =X509_NAME_get_index_by_NID(name, nidL, -1);
X509_NAME_ENTRY*subNameEntryL =X509_NAME_get_entry(name, indexL);
if(subNameEntryL) {
ASN1_STRING*subNameASN1L =X509_NAME_ENTRY_get_data(subNameEntryL);
if(subNameASN1L !=NULL) {
unsigned char*issuerName =ASN1_STRING_data(subNameASN1L);
[subObjectName appendFormat:@"L=%@,",[NSString stringWithUTF8String:(char*)issuerName]];
}
}
long nidE =OBJ_txt2nid("emailAddress");// organization
int indexE =X509_NAME_get_index_by_NID(name, nidE, -1);
X509_NAME_ENTRY*subNameEntryE =X509_NAME_get_entry(name, indexE);
if(subNameEntryE) {
ASN1_STRING*subNameASN1E =X509_NAME_ENTRY_get_data(subNameEntryE);
if(subNameASN1E !=NULL) {
unsigned char*issuerName =ASN1_STRING_data(subNameASN1E);
[subObjectName appendFormat:@"E=%@,",[NSString stringWithUTF8String:(char*)issuerName]];
}
}
long nidT =OBJ_txt2nid("telephoneNumber");// organization
int indexT =X509_NAME_get_index_by_NID(name, nidT, -1);
X509_NAME_ENTRY*subNameEntryT =X509_NAME_get_entry(name, indexT);
if(subNameEntryT) {
ASN1_STRING*subNameASN1T =X509_NAME_ENTRY_get_data(subNameEntryT);
if(subNameASN1T !=NULL) {
unsigned char*issuerName =ASN1_STRING_data(subNameASN1T);
[subObjectName appendFormat:@"TelephoneNumber=%@,",[NSString stringWithUTF8String:(char*)issuerName]];
}
}
long nidC =OBJ_txt2nid("CN");// organization
int indexC =X509_NAME_get_index_by_NID(name, nidC, -1);
X509_NAME_ENTRY*subNameEntryC =X509_NAME_get_entry(name, indexC);
if(subNameEntryC) {
ASN1_STRING*subNameASN1C =X509_NAME_ENTRY_get_data(subNameEntryC);
if(subNameASN1C !=NULL) {
unsigned char*issuerName =ASN1_STRING_data(subNameASN1C);
[subObjectName appendFormat:@"CN=%@",[NSString stringWithUTF8String:(char*)issuerName]];
}
}
}
return subObjectName;
}
/// 证书的过期日期时间
static NSDate*CertificateGetExpiryDate(X509*certificateX509)
{
NSDate*expiryDate =nil;
if(certificateX509 !=NULL) {
ASN1_TIME*certificateExpiryASN1 =X509_get_notAfter(certificateX509);
if(certificateExpiryASN1 !=NULL) {
ASN1_GENERALIZEDTIME*certificateExpiryASN1Generalized =ASN1_TIME_to_generalizedtime(certificateExpiryASN1,NULL);
if(certificateExpiryASN1Generalized !=NULL) {
unsigned char*certificateExpiryData =ASN1_STRING_data(certificateExpiryASN1Generalized);
// ASN1 generalized times look like this: "20131114230046Z"
// format: YYYYMMDDHHMMSS
// indices: 01234567890123
// 1111
// There are other formats (e.g. specifying partial seconds or
// time zones) but this is good enough for our purposes since
// we only use the date and not the time.
//
// (Source: http://www.obj-sys.com/asn1tutorial/node14.html)
NSString*expiryTimeStr = [NSString stringWithUTF8String:(char*)certificateExpiryData];
NSDateComponents*expiryDateComponents = [[NSDateComponents alloc]init];
expiryDateComponents.year = [[expiryTimeStr substringWithRange:NSMakeRange(0,4)]intValue];
expiryDateComponents.month = [[expiryTimeStr substringWithRange:NSMakeRange(4,2)]intValue];
expiryDateComponents.day = [[expiryTimeStr substringWithRange:NSMakeRange(6,2)]intValue];
expiryDateComponents.hour = [[expiryTimeStr substringWithRange:NSMakeRange(8,2)]intValue];
expiryDateComponents.minute= [[expiryTimeStr substringWithRange:NSMakeRange(10,2)]intValue];
expiryDateComponents.second= [[expiryTimeStr substringWithRange:NSMakeRange(12,2)]intValue];
NSCalendar*calendar = [NSCalendar currentCalendar];
expiryDate = [calendar dateFromComponents:expiryDateComponents];
// [expiryDateComponents release];
}
}
}
return expiryDate;
}
///获取证书生效日期
static NSDate * CertificateSignBeginDate(X509* certificateX509){
NSDate*signDate =nil;
if(certificateX509 !=NULL) {
ASN1_TIME*certificateExpiryASN1 =X509_get_notBefore(certificateX509);
if(certificateExpiryASN1 !=NULL) {
ASN1_GENERALIZEDTIME*certificateExpiryASN1Generalized =ASN1_TIME_to_generalizedtime(certificateExpiryASN1,NULL);
if(certificateExpiryASN1Generalized !=NULL) {
unsigned char*certificateExpiryData =ASN1_STRING_data(certificateExpiryASN1Generalized);
// (Source: http://www.obj-sys.com/asn1tutorial/node14.html)
NSString*expiryTimeStr = [NSString stringWithUTF8String:(char*)certificateExpiryData];
NSDateComponents*expiryDateComponents = [[NSDateComponents alloc]init];
expiryDateComponents.year = [[expiryTimeStr substringWithRange:NSMakeRange(0,4)]intValue];
expiryDateComponents.month = [[expiryTimeStr substringWithRange:NSMakeRange(4,2)]intValue];
expiryDateComponents.day = [[expiryTimeStr substringWithRange:NSMakeRange(6,2)]intValue];
expiryDateComponents.hour = [[expiryTimeStr substringWithRange:NSMakeRange(8,2)]intValue];
expiryDateComponents.minute= [[expiryTimeStr substringWithRange:NSMakeRange(10,2)]intValue];
expiryDateComponents.second= [[expiryTimeStr substringWithRange:NSMakeRange(12,2)]intValue];
NSCalendar*calendar = [NSCalendar currentCalendar];
signDate = [calendar dateFromComponents:expiryDateComponents];
}
}
}
return signDate;
}
static inline char itoh(int i) {
if(i >9)return'A'+ (i -10);
return'0'+ i;
}
验签过程:
EC_GROUP *sm2p256real = new_ec_group(1, "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF", "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFC","28E9FA9E9D9F5E344D5A9E4BCF6509A7F39789F515AB8F92DDBCBD414D940E93", "32C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7", "BC3736A2F4F6779C59BDCEE36B692153D0A9877CC62A474002DF32E52139F0A0", "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF40939D54123",
"1");
unsigned long_outlen;
NSString* uid = [self dealWithSubName:userIdjson:json];
NSString* removeSiginJsonStr = [NSString dealWithCodeJson:json];
// unsigned char _result[256];
siginStr = [siginStr uppercaseString];
NSData* siginData = [self dataFromHexString:siginStr];
_outlen = [siginData length];
NSString* px = publicKeyX;
NSString* py = publicKeyY;
if(!JZYT_sm2_verify(sm2p256real,
"",
[px cStringUsingEncoding:NSUTF8StringEncoding],
[py cStringUsingEncoding:NSUTF8StringEncoding],
[uid cStringUsingEncoding:NSUTF8StringEncoding],
[removeSiginJsonStr cStringUsingEncoding:NSUTF8StringEncoding], siginData.bytes,_outlen)){
returnNO;
}