NSURLAuthenticationMethodServerTrust验证服务器证书

时间:2015-03-11 09:47:41

标签: ios nsurlconnection nsurlconnectiondelegate

我正在根据服务器名称处理服务器的https身份验证,但我想基于服务器给我的证书来信任服务器。我怎么能这样做,任何帮助??

- (void)connection:(NSURLConnection *)connection
    didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
if ([challenge.protectionSpace.authenticationMethod
     isEqualToString:NSURLAuthenticationMethodServerTrust])
{
    // we only trust our own domain
    if ([challenge.protectionSpace.host isEqualToString:@"www.serverpage.com"])
    {
        NSURLCredential *credential =
            [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];
        [challenge.sender useCredential:credential forAuthenticationChallenge:challenge];
    }
}

[challenge.sender continueWithoutCredentialForAuthenticationChallenge:challenge];
}

我搜索了网页,发现大部分答案都是在没有验证的情况下接受任何服务器身份验证。

2 个答案:

答案 0 :(得分:0)

NSURLConnection有一个内置方法,可以使用不受信任的证书进行SSL。参见SO回答here。请确保您不要在生产代码中使用它,因为它很容易受到MITM攻击。

答案 1 :(得分:0)

您需要在应用内部封装服务器证书。 当您的应用启动时,您需要从封装的服务器证书中提取公钥。 在委托的回调URLSession:didReceiveChallenge:challenge:completionHandler中运行时 您需要遍历从提供的challenge.protectionSpace.serverTrust获取的证书 并与之前提取的公钥进行比较。

最好的事情 - 同样使用颁发者证书 - 在您的应用中包含原始证书,并使用challenge.protectionSpace.serverTrust

中的一个来调查它

下一个代码段演示了从证书中提取公钥:

SecKeyRef getPKeyFromCert(SecCertificateRef cert) {
    SecTrustRef newtrust = NULL;
    CFMutableArrayRef certs = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
    CFMutableArrayRef newPolicies = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
    CFArrayAppendValue(certs, cert);

    if (SecTrustCreateWithCertificates(certs, newPolicies, &newtrust) == errSecSuccess) {
        return SecTrustCopyPublicKey(newtrust);
    }
    return NULL;
}

下一个代码片段演示了通过protectSpace提供的证书的迭代:

SecTrustRef trustRef = challenge.protectionSpace.serverTrust;
CFIndex count = SecTrustGetCertificateCount(trustRef);
CFIndex i = 0;
for (i = 0; i < count; i++) {
    SecCertificateRef certRef = SecTrustGetCertificateAtIndex(trustRef, i);
    SecKeyRef publicKey = getPKeyFromCert(certRef);
    // do the magic
}