iOS Openssl 获取证书信息及验签

获取证书数据获取

+(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;

    }

你可能感兴趣的:(iOS Openssl 获取证书信息及验签)