检查预配文件的开发者证书有效性。

6
我希望能够让客户上传他们自己的配置文件,包括图标,这样我就可以即时为他们制作一个定制版本的应用程序,供他们发布使用。
然而,我在验证配置文件时遇到了一些问题。特别是,我想检查DeveloperCertificate是否实际上是一个有效的证书。该配置文件大致如下:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>ApplicationIdentifierPrefix</key>
    <array>
        <string>ABCDEFGH</string>
    </array>
    <key>CreationDate</key>
    <date>2012-03-28T11:17:23Z</date>
    <key>DeveloperCertificates</key>
    <array>
        <data>
        MIIFajCCBFKgAwIBAgIIddUra9YprMQwDQYJKoZIhvcNAQEFBQAwgZYxCzAJ
        BgNVBAYTAlVTMRMwEQYDVQQKDApBcHBsZSBJbmMuMSwwKgYDVQQLDCNBcHBs
        ZSBXb3JsZHdpZGUgRGV2ZWxvcGVyIFJlbGF0aW9uczFEMEIGA1UEAww7QXBw
        ...     
        </data>
    </array>
    ...
</dict>

所以,我提取了证书,然后想要使用 openssl 命令进行检查。这些证书使用了哪种加密方式?如何使用 openssl 进行验证?我认为这应该使用 pkcs12,但尝试时出现错误:

$ openssl pkcs12 -noout -in testcertificate
140653159306912:error:0D0680A8:asn1 encoding routines:ASN1_CHECK_TLEN:wrong tag:tasn_dec.c:1319:
140653159306912:error:0D07803A:asn1 encoding routines:ASN1_ITEM_EX_D2I:nested asn1 error:tasn_dec.c:381:Type=PKCS12

有没有人能指点我一下?我需要某种方式来验证开发者证书的有效性,这非常重要。

谢谢。

2个回答

9
我一直在研究这个问题,事实证明不需要像 David 描述的那样难。解决方案其实非常简单:
证书是一个 base64 编码的 DER 证书。您需要执行以下操作:
提取 XML 中的证书。
对证书进行 base64 解码:
base64 -d certificate > certificate.crt
使用 OpenSSL 测试证书:
openssl x509 -inform DER -in certificate.crt -noout -text
或者,如果我们使用管道:
cat certificate | base64 -d - | openssl x509 -inform DER -noout -text
< p > -text 选项会让 OpenSSL 提供所有细节,但您可以根据自己的需要进行指定。例如,假设您只想知道证书是否为实际的分发证书,则可以使用 -subject 选项代替,并查看 CN= 字段。


3
至少在我安装的 OS X 10.7.4 上,/usr/bin/base64 命令使用 -D 参数进行解码,而不是 -d 参数。因此完整的命令应该是 cat certificate | base64 -D - | openssl x509 -inform DER -noout -text - Phil Calvin
我是在Linux上做这个的,因此Mac OS X使用不同的参数是完全可能的。感谢添加! - Doa

0

好消息和坏消息都有。我有一个朋友是Mac/iOS的安全专家,他在这个领域做了很多工作。他实际上也需要做类似的事情。我从他那里得到的信息如下。但坏消息是没有命令行方式来完成它 - 你很可能需要使用以下技术之一来编写一个Mac应用程序来完成它。

-- 技术 ---

XML文件中的证书...被读入NSData对象中;虽然通常有3个证书;至少在Apple生成的配置文件中是这样的。不知道是否是这种情况。

如果有3个证书,通常检查其中一个(通常是最后一个)是否被称为“Apple Root CA”,并具有十六进制值为“611E5B662C593A08FF58D14AE22452D198DF6C60”的SHA1值 - 我使用openssl.h中的SHA1函数进行检查。

如果只有一个证书,那可能是叶子证书。要检查它是否正确,更加复杂,因为通常需要完整的“信任链”进行验证。

无论如何,您都必须链接Security.framework,使用NSData(适当转换)调用SecCertificateCreateWithData()以获取SecCertificateRef。

一个相对简便的方法是调用SecCertificateCopyValues()函数来获取“Authority Key Identifier (2.5.29.35)”字段(该字段的字典键似乎是kSecOIDAuthorityKeyIdentifier),并检查该字段的值是否为十六进制“E7342A2E22DE39606BB494CE7783612F31A07C35”,这似乎对所有由苹果颁发的证书都成立。SecCertificateCopyValues()的返回值是一个嵌套的字典-字典,因此必须深入查找才能找到它。
完整和详细的答案是将证书引用传递给SecTrustSettingsCopyTrustSettings()函数,并连续使用kSecTrustSettingsDomainUser、kSecTrustSettingsDomainAdmin、kSecTrustSettingsDomainSystem参数,检查证书是否被明确信任或不被信任。除非中间证书安装在机器上,否则如果它是叶子证书,这种方法可能会失败。

谢谢David。虽然不是我想要的(请看我的回答),但仍然是一个非常好的答案。由于我不能把赏金给自己,所以我会授予你的 :) - Doa

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接