簡體   English   中英

iOS HTTPS請求101

[英]iOS HTTPS requests 101

NSURLConnection/CFURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9813)

非常非常令人沮喪! 我一直在用頭發拉幾個小時。 我在Linode服務器上使用自簽名證書。 端口是8000,無法在443上工作。我不相信這是原因。 這是我的代碼,它是99%的樣板:

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

天啊幫忙!

UPDATE

它使用了這種委托方法。 我收到了回復,但是有問題。

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

}

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

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

獲取相應的錯誤說明可能有所幫助:

因此,首先錯誤域kCFStreamErrorDomainSSL意味着錯誤代碼是Security / SecureTransport.h中定義的SSL錯誤代碼:

kCFStreamErrorDomainSSL,-9813表示:

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

這只是意味着,您沒有受信任的根證書,並且由於該身份驗證失敗,連接失敗。

在設備上提供服務器信任身份驗證的根證書,你沒事。

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

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

使用自簽名證書實現服務器信任身份驗證

這些也必須閱讀: 技術說明TN2232 HTTPS服務器信任評估技術問答QA1360描述kSecTrustResultUnspecified錯誤

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

步驟類似:

  1. Bundel您的應用程序中CA的根證書的DER文件。
  2. 處理服務器信任身份驗證,如下所示:

    1. 獲得身份驗證挑戰
    2. 從挑戰中檢索信任對象
    3. 從捆綁中的數據創建證書對象
    4. 使用函數SecTrustSetAnchorCertificates將證書對象設置為信任對象的SecTrustSetAnchorCertificates
    5. 評估信任

不確定這是否能真正解決問題,但它可能有所幫助。 你應該使用

– connection:willSendRequestForAuthenticationChallenge:

因為其他方法已被棄用。 看一下NSURLConnectionDelegate協議的概述

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM