我已經將自簽名X509證書導入到我的iPhone中,只需將certificate.pem發送給它並安裝到設備上即可。現在我想驗證我的iOS應用程序中必須使用上述證書籤名的特定證書。基本上,導入的證書充當CA的根證書。iOS導入自簽名和自行創建的CA證書
導入的證書是否存儲在鑰匙串中?
如何以編程方式驗證基於導入的另一個證書? (第二個證書只有在被導入前的CA證書籤名時纔有效)
有沒有人有過這些場景的經驗?
在此先感謝!
我已經將自簽名X509證書導入到我的iPhone中,只需將certificate.pem發送給它並安裝到設備上即可。現在我想驗證我的iOS應用程序中必須使用上述證書籤名的特定證書。基本上,導入的證書充當CA的根證書。iOS導入自簽名和自行創建的CA證書
導入的證書是否存儲在鑰匙串中?
如何以編程方式驗證基於導入的另一個證書? (第二個證書只有在被導入前的CA證書籤名時纔有效)
有沒有人有過這些場景的經驗?
在此先感謝!
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()
;然後SHA1 NSData
與您的硬編碼sha1進行比較,以確保對其進行驗證。
謝謝!正是我在找什麼。順便說一下,是否也可以從鑰匙串中獲取/提取整個證書? (例如,如果您在代碼中將NSData用作鑰匙串中的NSData,但它是使用Apple的iPhone配置實用程序或任何其他MDM部署的?) – Chris 2012-07-20 17:59:14
是的 - 下面是我使用的代碼。實際上,如果你需要一個預先確定的標識符,它實際上會多一點。對不起,格式化 - 但評論是有點困難的代碼。隨意創建一個問題,以便我可以正確剪切和粘貼。 CFDictionaryCreate(),SecItemCopyMatching(),檢查SecIdentityGetTypeID()強制轉換,CFDataRef der = SecCertificateCopyData(cert); const unsigned char * ptr = CFDataGetBytePtr(der); long len = CFDataGetLength(der); d2i_X509(&x509,&ptr,len); _sha1 = [(__bridge NSData *)der sha1]; _der =(__bridge_transfer NSData *)der; CFRelease(der); – 2012-07-22 10:39:27
我試過你的代碼(和Apple的示例代碼),但它總是在'SecTrustEvaluate'上崩潰。新帖子:http://stackoverflow.com/questions/11608847/always-exc-bad-access-on-sectrustevaluate – Chris 2012-07-23 08:26:27