我正在根据服务器名称处理服务器的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];
}
我搜索了网页,发现大部分答案都是在没有验证的情况下接受任何服务器身份验证。
答案 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
}