2013-10-07 19 views
8

Java実行SSLServerSocketへの安全な接続をセットアップしようとしています。SSLソケット接続iOS

自分のルートCAを作成し、この証明書を使用してJava SSLServerSocketの証明書に署名しました。

このルート証明書をアプリケーションに追加して、ルート証明書で署名された証明書が動作するようにしたいとします。

これまでのところ私は、読み取りを設定することで、細かい作業の安全な接続を持っており、これにストリームのプロパティを記述します。

NSDictionary *settings = [[NSDictionary alloc] initWithObjectsAndKeys: 
(id)kCFStreamSocketSecurityLevelNegotiatedSSL, kCFStreamPropertySocketSecurityLevel, 
[NSNumber numberWithBool:YES], kCFStreamSSLAllowsExpiredCertificates, 
[NSNumber numberWithBool:YES], kCFStreamSSLAllowsExpiredRoots, 
[NSNumber numberWithBool:NO], kCFStreamSSLValidatesCertificateChain,nil]; 

私はこのようなキーチェーンに証明書を追加します。

-(void)addRootCert{ 
NSString* rootCertPath = [[NSBundle mainBundle] pathForResource:@"rootCA" ofType:@"der"]; 
NSData* rootCertData = [NSData dataWithContentsOfFile:rootCertPath]; 

OSStatus err = noErr; 
SecCertificateRef rootCert = SecCertificateCreateWithData(kCFAllocatorDefault, (__bridge CFDataRef)rootCertData); 
NSDictionary* dict = [NSDictionary dictionaryWithObjectsAndKeys:(__bridge_transfer id)kSecClassCertificate, kSecClass, rootCert, kSecValueRef, nil]; 

err = SecItemAdd((__bridge CFDictionaryRef) dict, NULL); 
if (err == noErr) { 
    NSLog(@"Sucessfully added root certificate"); 
}else if (err == errSecDuplicateItem){ 
    NSLog(@"Root certificate already exists"); 
}else{ 
    NSLog(@"Root certificate add failed"); 
} 
} 

これは、私のアプリケーションが自分のCA(またはデフォルトの信頼できる証明書)によって署名された証明書のみを受け入れるように証明書チェーンを検証したいのですが。

どうすればいいですか?

私はyesにkCFStreamSSLValidatesCertificateChainを設定した場合、私はエラーを取得する:CFNetwork SSLHandshake failed (-9807)が、それは何だ場合、それはサーバ証明書に署名した人は関係ありません、それは(私はそうですと仮定?)にかかわらず、

感謝を接続しないでしょう!

答えて

6

Technote 2232「HTTPSサーバーの信頼性評価」に必要なすべての回答が必要です。サーバーの信頼性を評価する方法のドキュメントといくつかの例があります。

+0

'SecTrustSetAnchorCertificates'の使用につきましては、私は自分のルートCAを追加したいと思っていますが、' SecTrustRef'はありません。どのようにすればいいですか?私が見たすべての例では、NSURLConnectionデリゲートメソッドを使用していますが、ソケットを使用しています。 –

+3

これはおそらくあなたが探しているものです:https://developer.apple.com/library/mac/documentation/NetworkingInternet /Conceptual/NetworkingTopics/Articles/OverridingSSLChainValidationCorrectly.html – quellish

+0

ありがとうございました、その最後のリンクは完璧でした! –

0

私はこの同じ問題を抱えていたし、証明書を手動で追加するともアプリに、私にこのようなことの有効期限が切れたときのように、サーバーの変更(、上の証明書をすべての時間を更新することを意味し、問題を修正しながら、ケースは、数日で起こるだろう)。

IPアドレスを使用してソケットに接続し、証明書がFQDN(完全修飾ドメイン名、つまりsubdomain.example.com)用である場合、オペレーティングシステムが証明書をチェックすると、証明書は次のようになります。あなたが接続しているIPアドレスを見て、証明書の名前と比較して、2つが異なっていると考えて、チェーンが検証に失敗する原因になります。

この問題に遭遇する人は、IPアドレスではなくCFStreamCreatePairWithSocketToHostの2番目のパラメータでFQDNを使用することをお勧めします。その後、の証明書をバンドルに含めずに手動で検証する必要がありません。