如何在macOS中获取已签名pkg文件的可信时间戳?
获取pkg文件签名可信时间戳的高效编程方法
现有方法的局限性
- 已签名的.app/二进制文件可通过Security框架的
SecStaticCodeRef调用SecCodeCopySigningInformation获取signing-timestamp(对应kSecCodeInfoTimestamp),但这套API对pkg文件无效。 - 借助xar API(如
xar_signature_get_x509certificate_data)能获取颁发者、序列号、证书有效期等信息,但无法提取pkg签名时的可信时间戳,暂无对应API。 - 通过代码执行
pkgutil --check-signature并解析输出,小体积pkg可正常使用,但12.2GB级别的InstallAssistant.pkg这类大文件,执行命令耗时约22秒,效率极低。
高效解决方案:直接解析pkg签名结构,跳过全量校验
pkg本质是xar归档文件,签名信息存储在归档的签名区段中,无需校验整个包的完整性即可提取时间戳,步骤如下:
打开xar归档
使用xar API仅加载签名相关元数据,不读取整个包内容:xar_t xar = xar_open("/path/to/target.pkg", READ); if (!xar) { // 处理打开失败逻辑 }获取签名对象
从xar中提取签名结构:xar_signature_t sig = xar_signature_first(xar); if (!sig) { // 包未签名,处理错误后关闭归档 xar_close(xar); }提取时间戳令牌
可信时间戳以RFC 3161格式的令牌存储,通过xar API获取原始令牌数据:const unsigned char *ts_token_data = NULL; size_t ts_token_len = 0; if (xar_signature_get_timestamp_token(sig, &ts_token_data, &ts_token_len) != 0) { // 无时间戳,处理后关闭归档 xar_close(xar); }解析时间戳令牌获取时间
可使用Security框架或OpenSSL解析RFC 3161令牌,以下是OpenSSL简化示例:CMS_ContentInfo *cms = d2i_CMS_ContentInfo(NULL, &ts_token_data, ts_token_len); if (cms) { STACK_OF(CMS_SignerInfo) *signers = CMS_get0_signers(cms); if (signers && sk_CMS_SignerInfo_num(signers) > 0) { CMS_SignerInfo *si = sk_CMS_SignerInfo_value(signers, 0); ASN1_TIME *ts_time = CMS_SignerInfo_get_signing_time(si); if (ts_time) { // 将ASN1_TIME转换为可读格式,如NSDate(Objective-C)或struct tm(C) char time_buf[100]; ASN1_TIME_print(BIO_new_fp(stdout, BIO_NOCLOSE), ts_time); // 自定义格式转换逻辑 } } CMS_ContentInfo_free(cms); }清理资源
完成操作后关闭xar归档:xar_close(xar);
性能优势
该方法仅读取pkg的元数据区段,不扫描整个大文件内容,避免了pkgutil --check-signature的全量校验步骤,大文件下耗时可缩短至毫秒级。
参考示例(执行
pkgutil --check-signature zoomusInstallerFull.pkg输出):Status: signed by a developer certificate issued by Apple for distribution Notarization: trusted by the Apple notary service Signed with a trusted timestamp on: 2022-06-27 01:26:22 +0000 Certificate Chain: Developer ID Installer: Zoom Video Communications, Inc. (BJ4HAAB9B3) Expires: 2027-02-01 22:12:15 +0000 SHA256 Fingerprint: 6D 70 1A 84 F0 5A D4 C1 C1 B3 AE 01 C2 EF 1F 2E AE FB 9F 5C A6 80 48 A4 76 60 FF B5 F0 57 BB 8C ------------------------------------------------------------------------ Developer ID Certification Authority Expires: 2027-02-01 22:12:15 +0000 SHA256 Fingerprint: 7A FC 9D 01 A6 2F 03 A2 DE 96 37 93 6D 4A FE 68 09 0D 2D E1 8D 03 F2 9C 88 CF B0 B1 BA 63 58 7F ------------------------------------------------------------------------ Apple Root CA Expires: 2035-02-09 21:40:36 +0000 SHA256 Fingerprint: B0 B1 73 0E CB C7 FF 45 05 14 2C 49 F1 29 5E 6E DA 6B CA ED 7E 2C 68 C5 BE 91 B5 A1 10 01 F0 24
内容的提问来源于stack exchange,提问作者Tushar
相关产品推荐
相关产品推荐

