iOS导入自签名和自行创建的CA证书

时间:2012-07-20 12:58:50

标签: iphone validation certificate x509 trust

我已将自签名X509证书导入我的iPhone,只需将certificate.pem通过电子邮件发送到我的iPhone并将其安装到设备上即可。现在,我想验证我的iOS应用程序中必须使用上述证书签名的特定证书。基本上,导入的证书充当CA的根证书。

导入的证书是否存储在钥匙串中?

如何基于导入的证书以编程方式验证另一个证书? (第二个证书仅在由导入的CA证书签名之前有效)

有没有人对这些情景有一些经验?

提前致谢!

1 个答案:

答案 0 :(得分:3)

1)是的 - 它位于您的钥匙串中。

2)您使用信任SecTrustCreateWithCertificates()SecTrustEvaluate()对所有证书或您自己的证书进行验证。

3)如果您针对广泛的证书进行了验证,您可以选择在钥匙串中查找自己的证书;得到DER;计算其SHA1并将其与代码中硬编码的SHA1进行比较。

代码如下所示。

NSMutableArray *serverChain = -- array with what you want to check
NSMutableArray *trustedCertRefs = <your-hardcoded-certs>;

SecTrustRef noHostTrustRef = NULL;
OSErr status = SecTrustCreateWithCertificates((__bridge CFArrayRef)serverChain,
                                 SecPolicyCreateSSL(NO, nil), &noHostTrustRef);

if (status != noErr) {
    NSLog(@"SecTrustCreateWithCertificates failed: %hd", status);
    [[challenge sender] cancelAuthenticationChallenge:challenge];
}


status = SecTrustSetAnchorCertificates(noHostTrustRef,
                         (__bridge CFArrayRef)trustedCertRefs);
if (status != noErr) {
    NSLog(@"SecTrustSetAnchorCertificates failed: %hd", status);
    [[challenge sender] cancelAuthenticationChallenge:challenge];
}

status = SecTrustEvaluate(noHostTrustRef, &result);
if (status != noErr) {
    NSLog(@"SecTrustEvaluate failed: %hd", status);
    [[challenge sender] cancelAuthenticationChallenge:challenge];
}
CFRelease(noHostTrustRef);

/* From SecTrust.h:
 *
 * SecTrustResultType results have two dimensions.  They specify both whether 
 * evaluation suceeded and whether this is because of a user decision.  
 *
 * In practice the commonly expected result is kSecTrustResultUnspecified,
 * which indicates a positive result that wasn't decided by the user.  
 *
 * The common failure is kSecTrustResultRecoverableTrustFailure, which means a
 * negative result.  kSecTrustResultProceed and kSecTrustResultDeny are the
 * positive and negative result respectively when decided by the user.  User
 *  decisions are persisted through the use of SecTrustCopyExceptions() and
 * SecTrustSetExceptions().  Finally kSecTrustResultFatalTrustFailure is a
 * negative result that should not be circumvented.  In fact only in the case
 * of kSecTrustResultRecoverableTrustFailure should a user ever be asked.
 */
switch (result) {
    case kSecTrustResultProceed: // 1
    case kSecTrustResultConfirm: // 2
    case kSecTrustResultUnspecified: // 4
        return YES
        break;
    case kSecTrustResultRecoverableTrustFailure:  // 5
    case kSecTrustResultDeny: // 3
    case kSecTrustResultFatalTrustFailure: // 6
    case kSecTrustResultOtherError: // 7
    case kSecTrustResultInvalid: // 0
    default:
        return NO:
        break;
}
[[challenge sender] cancelAuthenticationChallenge:challenge];

或者如果您获得了一个信任链,比如已经根据钥匙串验证的网络堆栈(从而违反了您的证书),那么您可以提取证书;对他们做SecCertificateCopyData();然后将NSData与你的硬编码sha1进行比较的SHA1,以确保它完全针对那个进行验证。

相关问题