我在這裏看到幾個問題,但他們都沒有幫助我。人們通常會解決問題,主要是重新生成服務器證書:What is the reason of kSecTrustResultRecoverableTrustFailure?kSecTrustResultRecoverableTrustFailure使用NSURLConnection連接到使用自簽名證書的https
假設我需要使用自簽名證書與服務器進行https連接。我沒有來自服務器的任何內部數據,例如其私鑰。例如,服務器是https://www.pcwebshop.co.uk/
據我瞭解,我可以將客戶端證書捆綁到應用程序中,並將其用於驗證。我是否可以在沒有來自服務器的任何內部數據的情況下獲得有效的客戶端證書?
我GOOGLE了這裏的教程http://www.indelible.org/ink/trusted-ssl-certificates
這裏是我如何獲得客戶端證書
openssl s_client \
-showcerts -connect "${HOST}:443" </dev/null 2>/dev/null | \
openssl x509 -outform DER >"../resources/${HOST}.der"
下面的代碼(幾乎不變):
- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace
{
return [protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust];
}
- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
if ([self shouldTrustProtectionSpace:challenge.protectionSpace]) {
[challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]
forAuthenticationChallenge:challenge];
} else {
[challenge.sender performDefaultHandlingForAuthenticationChallenge:challenge];
}
}
- (BOOL)shouldTrustProtectionSpace:(NSURLProtectionSpace *)protectionSpace
{
// load up the bundled certificate
NSString *certPath = [[NSBundle mainBundle] pathForResource:protectionSpace.host ofType:@"der"];
if (certPath == nil)
return NO;
OSStatus status;
NSData *certData = [[NSData alloc] initWithContentsOfFile:certPath];
CFDataRef certDataRef = (__bridge_retained CFDataRef)certData;
SecCertificateRef cert = SecCertificateCreateWithData(NULL, certDataRef);
// establish a chain of trust anchored on our bundled certificate
CFArrayRef certArrayRef = CFArrayCreate(NULL, (void *)&cert, 1, NULL);
SecTrustRef serverTrust = protectionSpace.serverTrust;
status = SecTrustSetAnchorCertificates(serverTrust, certArrayRef);
// status == 0
// verify that trust
SecTrustResultType trustResult;
status = SecTrustEvaluate(serverTrust, &trustResult);
// status == 0
CFRelease(certArrayRef);
CFRelease(cert);
CFRelease(certDataRef);
return trustResult == kSecTrustResultUnspecified;
}
trustResult總是kSecTrustResultRecoverableTrustFailure。
我在做什麼錯?謝謝。
UPDATE:好的,我發現原因是「服務器的證書與URL不匹配」。
是否可以通過忽略服務器證書的URL(主機名)來解決客戶端問題?
好的,現在我決定只是將服務器證書與本地副本進行比較,並檢查主機名的IP地址是否與我的本地副本匹配。希望我能找到如何檢索服務器證書和IP地址的工作示例=/ – alopatindev
這是很好的策略。其稱爲證書鎖定。 IP塊很適合。你不希望有一天看到美國或英國的IP地址,然後看到下一個俄羅斯IP。可能會發生一些魚腥味...... – jww