2013-08-03 112 views
14
NSURLConnection/CFURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9813) 

非常非常令人沮喪!我已經用這個拉了幾個小時的頭髮。我在我的Linode服務器上使用自簽名證書。端口是8000,無法在443上運行。我不認爲這是原因。這裏是我的代碼,這是99%的樣板:iOS HTTPS請求101

NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"https://www.myserver.com:8000/test.json"]]; 
NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:YES]; 

在底部:

#pragma mark NSURLConnectionDelegate 

- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace { 
    NSLog(@"protectionSpace: %@", [protectionSpace authenticationMethod]); 

    // We only know how to handle NTLM authentication. 
    if([[protectionSpace authenticationMethod] isEqualToString:NSURLAuthenticationMethodNTLM]) 
     return YES; 

    // Explicitly reject ServerTrust. This is occasionally sent by IIS. 
    if([[protectionSpace authenticationMethod] isEqualToString:NSURLAuthenticationMethodServerTrust]) 
     return NO; 

    return NO; 
} 

- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge { 
    [[challenge sender] continueWithoutCredentialForAuthenticationChallenge:challenge]; 
} 

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response { 
    NSLog(@"%@", response); 
} 

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data { 
    NSLog(@"%@", data); 
} 

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error { 
    NSLog(@"didFailWithError"); 
    NSLog([NSString stringWithFormat:@"Connection failed: %@", [error description]]); 
} 

OMG幫助!

UPDATE

它的工作與此委託方法。我收到了回覆,但有一個問題。

- (void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge { 
    [[challenge sender] useCredential:[NSURLCredential 
             credentialWithUser:@"user" 
             password:@"password" 
             persistence:NSURLCredentialPersistencePermanent] forAuthenticationChallenge:challenge]; 

} 

我提供的「用戶」和「密碼」是完全隨機的,不會被服務器檢查。 如何在接受我的服務器上的連接之前驗證憑據?

編輯:我運行的Node.js服務器

+0

’的‘用戶’和」密碼 - 這是一個不同的問題。你應該把它作爲一個單獨的問題來問,也許可以回到這個問題上。 Linode配置可能是無關緊要的,所以您可能不得不徘徊到超級用戶或服務器故障。 (你應該接受Fonix的回答,因爲它似乎幫助你解決了這個問題)。 – jww

回答

2

不知道這是否會真正解決問題,但它可能會有所幫助。您應該使用

– connection:willSendRequestForAuthenticationChallenge: 

因爲其他方法已被棄用。看一看的NSURLConnectionDelegate protocol

+0

幾乎工作,看到我更新的問題 –

+0

不幸的是我有點noob這個身份驗證的東西,所以我不知道 – Fonix

8

獲取相應的錯誤描述概覽可以幫助:

因此,第一誤差域kCFStreamErrorDomainSSL意味着錯誤代碼是在安全/ SecureTransport.h定義的SSL錯誤代碼:

kCFStreamErrorDomainSSL,-9813表示:

errSSLNoRootCert = -9813, /* cert chain not verified by root */

這只是意味着,你有沒有受信任的根證書和連接到由於該認證失敗,ction失敗。

在設備上爲服務器信任認證提供根證書,你很好。

有幾種方法可以使用自簽名證書實現服務器信任認證,這是一種比另一種更安全的方法。

最簡單的方法需要存儲在應用程序包中的自簽名證書,然後進行檢索並進行字節比較。這裏是一個例子:

Implementing server trust authentication with a self-signed certificate

這些是必讀:Technical Note TN2232 HTTPS Server Trust EvaluationTechnical Q&A QA1360 Describing the kSecTrustResultUnspecified error

更優選的方法是使用您可以自己做的CA(證書頒發機構)。也就是說,您創建了自己的CA,並使用此CA簽署了證書。

的步驟類似:

  1. Bundel您的CA根證書在您的應用程序的DER文件。
  2. 處理服務器信任認證如下:

    1. 獲得認證挑戰
    2. 從挑戰
    3. 獲取信任的對象在你的包的數據創建一個證書對象
    4. 設置證書對象作爲使用函數SecTrustSetAnchorCertificates的信任對象的錨點。
    5. 評估「我提供的是完全隨機的,而不是由服務器檢查‘信任
+4

這裏是解密其他錯誤代碼的URL ... http://www.opensource.apple.com/源極/ libsecurity_ssl/libsecurity_ssl-36800/LIB/SecureTransport.h – cat