3

iOSアプリケーションを開発しています。自己署名CA証明書を使用したカスタム認証局があります。証明機関は、ユーザーとhttpsサーバーの両方に対しても証明書を発行します。ca証明書を使用してhttpsサーバーを認証し、クライアント証明書を使用してhttpsサーバーと通信できるiOSアプリケーションを作成したいと思います。クライアント証明書を使用してhttpsサーバーと通信するためのコードはすでに持っていますが、ca-certificateをシステムキーリングにインポートする必要があります。アプリケーションにCA証明書をハードコードしてもらいたいのですが。私のコードは次のようになります:

- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace {

    bool result=NO;
    if ([protectionSpace authenticationMethod] == NSURLAuthenticationMethodServerTrust) {
        result= YES;
    } else if([protectionSpace authenticationMethod] ==     NSURLAuthenticationMethodClientCertificate) {
        result = YES;
    }
    return result;
}

- (BOOL)shouldTrustProtectionSpace:(NSURLProtectionSpace *)protectionSpace {
    CFDataRef certDataRef = (__bridge_retained CFDataRef)self.rootCertData;
    SecCertificateRef cert = SecCertificateCreateWithData(NULL, certDataRef);

    SecTrustRef serverTrust = protectionSpace.serverTrust;

    CFArrayRef certArrayRef = CFArrayCreate(NULL, (void *)&cert, 1, NULL);
    SecTrustSetAnchorCertificates(serverTrust, certArrayRef);

    SecTrustResultType trustResult;
    SecTrustEvaluate(serverTrust, &trustResult);

    return  trustResult == kSecTrustResultUnspecified;
}

- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {

    NSLog(@"Did receive auth challange %@",[challenge debugDescription]);

    NSURLProtectionSpace *protectionSpace = [challenge protectionSpace];

    NSString *authMethod = [protectionSpace authenticationMethod];
    if(authMethod == NSURLAuthenticationMethodServerTrust ) {
        NSLog(@"Verifying The Trust");

        NSURLCredential* cred=[NSURLCredential credentialForTrust:[protectionSpace serverTrust]];
        if ([self shouldTrustProtectionSpace:challenge.protectionSpace]) {
            [[challenge sender] useCredential:cred forAuthenticationChallenge:challenge];
            NSLog(@"OK");
        } else {
            NSLog(@"FAILED");
            [challenge.sender performDefaultHandlingForAuthenticationChallenge:challenge];
        }

    }
    if(authMethod == NSURLAuthenticationMethodClientCertificate ) {
        NSLog(@"Trying Certificate");
        .....

サーバーがクライアント証明書を必要としないまで、すべてが魅力のように機能します。この時点でエラーが発生しますこのサーバーの証明書は無効であり、実行はポイントに到達しません

 NSLog(@"Trying Certificate");

.der ca-certをシステムキーリングにロードすると、すべてが機能し、クライアント証明書もサーバーに送信され、サーバーはユーザーを認識できます。私はそれを

SecTrustSetAnchorCertificates(serverTrust, certArrayRef);

どういうわけか信頼に影響します、私がこの呼び出しをスキップするとき、私は単にすることができます:

[[challenge sender] useCredential:cred forAuthenticationChallenge:challenge];

エラーは発生していませんが、この場合、証明書を確認できません。

私は何が間違っているのですか?

どうもありがとう、アダム

4

1 に答える 1

2

このコードを見てください

https://github.com/dirkx/Security-Pinning-by-CA

これは、2つの信頼ブロックをかなり慎重に分離することで両方を行います(混合しているようです)。

于 2013-03-25T13:21:24.440 に答える