2

certificate.pem をメールで送信し、デバイスにインストールするだけで、自己署名 X509 証明書を iPhone にインポートしました。ここで、前述の証明書を使用して署名する必要がある iOS アプリケーションの特定の証明書を検証したいと思います。基本的に、インポートされた証明書は CA のルート証明書として機能します。

インポートされた証明書はキーチェーンに保存されますか?

インポートされた証明書に基づいて別の証明書をプログラムで検証するにはどうすればよいですか? (2 番目の証明書は、インポートされる前に CA 証明書によって署名されている場合にのみ有効です)

これらのシナリオを経験した人はいますか?

前もって感謝します!

4

1 に答える 1

3

1) はい - キーチェーンに入っています。

2) trust を使用して、すべての証明書または自分の証明書のみに対して検証し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 と比較して、正確にその sha1 に対して検証されるようにします。

于 2012-07-20T14:07:03.123 に答える