6

アプリのセキュリティを向上させ、ユーザーを MITM 攻撃から保護するために、この投稿の内容に従って、自己署名証明書を使用して SSL ピンニングを実行しようとしています。

そのため、次のコードを使用して、サーバーから取得した証明書とアプリにバンドルされている証明書を比較しています。

- (void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
    SecTrustRef serverTrust = challenge.protectionSpace.serverTrust;
    SecCertificateRef certificate = SecTrustGetCertificateAtIndex(serverTrust, 0);
    NSData *remoteCertificateData = CFBridgingRelease(SecCertificateCopyData(certificate));
    NSLog(@"Remote Certificate Data Length: %d",[remoteCertificateData length]);
    NSString *cerPath = [[NSBundle mainBundle] pathForResource:@"apache" ofType:@"crt"];
    NSData *localCertData = [NSData dataWithContentsOfFile:cerPath];
    NSLog(@"Local Certificate Data Length: %d",[localCertData length]);
    if ([remoteCertificateData isEqualToData:localCertData]) {
        NSURLCredential *credential = [NSURLCredential credentialForTrust:serverTrust];
        [[challenge sender] useCredential:credential forAuthenticationChallenge:challenge];
    }
    else {
        [[challenge sender] cancelAuthenticationChallenge:challenge];
    }
}

私のコードと私がリンクしたブログ投稿のコードとの唯一の違いは、私の証明書を表すリソースの名前と拡張子 (.cer から .crt) と、後で表示するのに便利な追加した 2 つの NSLog だけです。問題は何ですか。

実際、このコードを実行すると、次の出力が得られます。

2013-05-22 16:08:53.331 HTTPS Test[5379:c07] Remote Certificate Data Length: 880
2013-05-22 16:09:01.346 HTTPS Test[5379:c07] Local Certificate Data Length: 1249

データの長さが異なるため、ローカル証明書とリモート証明書の比較は明らかに失敗し、ピニングも失敗します。

この問題が発生する理由と、この問題を解決するにはどうすればよいですか?

4

1 に答える 1

5

同じ問題がありました。問題はおそらく、.crt ファイルを正しい形式に変換していないことが原因です。iOS と OSX は、 .der形式の証明書を探しています。変換するには、 opensslを使用する必要があります。これは、このトピックに関する非常に役立つ記事です。私の公開証明書は Apache サーバーからのものです (あなたの証明書もそうだったと思います)。openssl のドキュメントを調べた後、これを機能させる方法を理解することができました。

1) ターミナルを開き、ディレクトリを .crt の場所に変更します。

2) 次のコマンドを実行します。

openssl x509 -in your_cert.crt -outform der -out your_output_name.der

これにより、「your_output_file.der」という名前の出力ファイルが作成されます。これを xCode プロジェクトにインポートして、

- (void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge

実装の方法NSURLConnectionDelegate

これが役立つことを願っています!

于 2014-02-20T16:09:22.663 に答える