美文网首页
Get certificate infomation

Get certificate infomation

作者: ienos | 来源:发表于2020-03-28 15:29 被阅读0次

举个🌰,比如说我们希望通过 App 获取存储在沙盒下的证书过期时间

获取本地证书

非 P12 证书获取

1.通过本地路径获取证书数据 Data
2.通过证书 Data 获取 CertificateRef

NSData *certData = [NSData dataWithContentsOfFile:path];
//    if (certData.length == 0) return ;
SecCertificateRef certRef = SecCertificateCreateWithData(NULL, (__bridge CFDataRef)certData);
//    if (!certRef) return ;
CFRelease(certRef);

P12 证书获取方式

  1. 通过路径获取证书数据 Data
  2. 通过 Import PCK 方法获取证书数组 CertIdentifyTrustDictArrays
  3. 通过证书的 Identify 创建 CertificateRef
CFDictionaryRef secImportOptions = (__bridge CFDictionaryRef) @{(__bridge id) kSecImportExportPassphrase : psk};
CFArrayRef secImportItems = NULL; // 证书列表
NSData *pk12Data = [NSData dataWithContentsOfFile:path];
OSStatus status = SecPKCS12Import((__bridge CFDataRef) pk12Data, (CFDictionaryRef) secImportOptions, &secImportItems);
if (status == errSecSuccess
    && secImportItems && CFArrayGetCount(secImportItems) > 0) {
    // Identify
    CFDictionaryRef myIdentityAndTrust = CFArrayGetValueAtIndex(secImportItems,0);
    const void*tempIdentity = NULL;
    tempIdentity = CFDictionaryGetValue(myIdentityAndTrust, kSecImportItemIdentity);
    SecIdentityRef identify = (SecIdentityRef)tempIdentity;
    SecCertificateRef certRef;
    OSStatus status = SecIdentityCopyCertificate(identify, &certRef);
    if (status == errSecSuccess) {
        SecCertificateRef certRef = SecCertificateCopyData(certRef);
        CFRelease(certRef);
    }
}

通过 SecCertificateRef 获取证书信息

目前暂未找到 Security Framework 有相关 Api

所以使用了开源库 Openssl-iOS GitHub

Openssl-iOS 的使用

下载完成后,打开项目根目录,推荐使用 Go2shell 工具,可以直接打开终端并进入当前目录路径下

运行 shell 脚本 ./build-libssl.sh 进行编译输出

最后在 lib 下找到 libssl.a、libcrypto.a 拉到项目中的 Framework
然后将 include 文件夹拉到项目文件夹中,但是可以不用拉到 .xcodeproj / .xcworkspace 中

最后一步,在 Target 中的 BuildSetting 搜索🔍 Header Search Paths 然后将 include 文件路径拖进去

这样就可以使用 Openssl-iOS

修改支持的指令集 [Optional]

我下载的那个版本中,build-libssl.sh 中定义了 Target 编译的指令集
DEFAULTTARGETS 字段中只支持 ios64-cross-arm64 ios64-cross-arm64e

后面导致我使用该库的项目中打包出现了报错,但是我使用真机编译运行的时候没有问题

原因就是因为我的项目中默认支持 armv7s,armv7,而在 Openssl-iOS 编译的时候静态库没有带这两个
该设置项在 TARGET -> Build Settings -> Architectures -> Valid Architectures 中


修改 build-libssl.h 中的 DEFAULTTARGETS

DEFAULTTARGETS="ios-cross-armv7s ios-cross-armv7 ios-sim-cross-x86_64 ios64-cross-arm64 ios64-cross-arm64e tvos-sim-cross-x86_64 tvos64-cross-arm64"

自己可根据需要进行增删

armv7 和 armv7s 是属于 32位 CPU, iOS 系统版本中,32 位仅支持到 iOS 10,所以如果使用 armv7 和 armv7s,需要同时修改 IOS_MIN_SDK_VERSION

IOS_MIN_SDK_VERSION="10.0" // 10.0 以下都可以

编译过程中可能会报错,Openssl-iOS 会输出对应 .log 日志,可以根据对应问题进行修改

通过 Openssl-iOS 获取证书时间

通过上面获取到的 SecCertificateRef 初始化 NSData,然后进行获取证书信息

初始化成 X509 还可以获取其他证书信息

NSData *data = CFBridgingRelease(SecCertificateCopyData(certRef));
const unsigned char *certificateDataBytes = [data bytes];
X509 *certificateX509 = d2i_X509(NULL, &certificateDataBytes, [data length]);
ASN1_TIME *not_before = X509_getm_notBefore(certificateX509);
ASN1_TIME *not_after = X509_getm_notAfter(certificateX509);
/// 证书过期时间
char not_after_str[DATE_LEN];
convert_ASN1TIME(not_after, not_after_str, DATE_LEN);

/// 证书创建时间
char not_before_str[DATE_LEN];
convert_ASN1TIME(not_before, not_before_str, DATE_LEN);

// 将时间转换为时间戳
NSMutableString *beforeString = [[NSMutableString alloc]initWithFormat:@"%s", not_before_str];
NSMutableString *afterString = [[NSMutableString alloc]initWithFormat:@"%s", not_after_str];
NSDateFormatter *formatter = [[NSDateFormatter alloc]init];
[formatter setDateFormat:@"MM dd  hh:mm:ss yyyy zzz"];
NSDate *afterDate = [formatter dateFromString:afterString];
NSTimeInterval afterTimeStamp = afterDate.timeIntervalSince1970;

convert_ASN1TIME 用于将 ASN1_Time 转换为 char[]

int convert_ASN1TIME(ASN1_TIME *t, char* buf, size_t len)
{
    int rc;
    BIO *b = BIO_new(BIO_s_mem());
    rc = ASN1_TIME_print(b, t);
    if (rc <= 0) {
        BIO_free(b);
        return EXIT_FAILURE;
    }
    rc = BIO_gets(b, buf, len);
    if (rc <= 0) {
        BIO_free(b);
        return EXIT_FAILURE;
    }
    BIO_free(b);
    return EXIT_SUCCESS;
}

Security API 中获取证书内容

相关文章

网友评论

      本文标题:Get certificate infomation

      本文链接:https://www.haomeiwen.com/subject/gplkuhtx.html