【问题标题】:NSURLAuthenticationMethodServerTrust validation for server certificate服务器证书的 NSURLAuthenticationMethodServerTrust 验证
【发布时间】:2015-05-13 00:56:45
【问题描述】:

我正在根据服务器名称处理服务器的 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];
}

我在网上搜索,发现大多数答案只是接受任何服务器身份验证而不验证。

【问题讨论】:

  • 出于好奇,您为什么要自己实现 SSL 握手?你不能使用像 AFNetworking 这样的库吗?
  • 我的应用没有 AFNetworking ,它只使用 NSURLConnection。
  • 我的理解是NSURLConnection 会自己做这件事。检查服务器名称是默认 SSL 握手的一部分。还是您尝试使用自签名证书进行连接?
  • 是的,它的自签名证书检查
  • 问题解决了吗?

标签: ios nsurlconnection nsurlconnectiondelegate


【解决方案1】:

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

【讨论】:

  • 谢谢丹尼斯,但我不想接受任何证书。我需要验证服务器的证书
【解决方案2】:

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

最好的事情 - 也对颁发者证书做同样的事情 - 在你的应用程序中包含它的原件,并使用从 challenge.protectionSpace.serverTrust 获得的一个来调查它

下一个代码 sn-p 演示从证书中提取公钥:

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;
}

下一个代码 sn-p 演示了通过 protectionSpace 提供的证书的迭代:

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
}

【讨论】:

    猜你喜欢
    • 2021-11-11
    • 2011-07-07
    • 2012-11-14
    • 2018-10-20
    • 2013-06-17
    • 2015-06-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多