4

我进行了广泛的搜索并进行了必要的更改(我认为)以符合 Appl'es ATS 限制。

私钥 2048 位或更高

openssl rsa -in privkey.pem -text -noout

私钥:(2048 位)

在 v1.2 验证的nginx ssl 上运行 ssl v1.2

甚至运行 make nscurl 实用程序来检查连接,所有测试都通过了。

我还可以通过从浏览器对 https 进行 GET 并让一切正常运行来验证服务器是否正常运行。

我的想法是可能是子域引起了问题,所以我将 info.plist 文件更新为以下内容

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"       "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSAppTransportSecurity</key>
<dict>
    <key>NSExceptionDomains</key>
    <dict>
        <key>boramash.com</key> (also tried gateway.boramash.com)
        <dict>
            <key>NSIncludesSubdomains</key>
            <true/>
        </dict>
    </dict>
</dict>

在我认为一切正常的情况下,我收到以下错误。

2016-01-25 15:59:17.345 StripePlayground[2999:84984] NSURLSession/NSURLConnection HTTP 加载失败 (kCFStreamErrorDomainSSL, -9802) 2016-01-25 15:59:17.348 StripePlayground[2999:84989] (null) 2016-01 -25 15:59:17.348 StripePlayground[2999:84989] 错误域=NSURLErrorDomain 代码=-1200 “发生 SSL 错误,无法与服务器建立安全连接。” UserInfo={NSURLErrorFailingURLPeerTrustErrorKey=, NSLocalizedRecoverySuggestion=您是否仍要连接到服务器?, _kCFStreamErrorDomainKey=3, _kCFStreamErrorCodeKey=-9802, NSErrorPeerCertificateChainKey={type = immutable, count = 1, values = ( 0 : )}, NSUnderlyingError=0x7fd97252e580 {错误域=kCFErrorDomainCFNetwork 代码=-1200 "(null)" UserInfo={_kCFStreamPropertySSLClientCertificateState=0,https://gateway.boramash.com/stripe-add-customer , NSErrorFailingURLStringKey= prependingtext_for_stack_overflowhttps://gateway.boramash.com/stripe-add-customer, NSErrorClientCertificateStateKey=0}

这也是我的请求代码,非常基本。

NSString *myrequest = @"https://gateway.boramash.com/stripe-add-customer";

// NSURL *newcustomerURL = [NSURL URLWithString:@"http//45.55.154.107:5050/create-customer"];
NSURL *newcustomerURL = [NSURL URLWithString: myrequest];

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL: newcustomerURL];
//request.HTTPBody = [[NSString stringWithFormat:@"customer_id=%@&first_name=%@&last_name=%@", testID, firstName, lastName] dataUsingEncoding: NSUTF8StringEncoding ];

request.HTTPMethod = @"GET";

[[[NSURLSession sharedSession] dataTaskWithRequest:request    completionHandler:^(NSData * _Nullable data, NSURLResponse *_Nullable  response, NSError * _Nullable error) {
    //print the result here - new customer has been created!
    NSString *myresponse = [NSString stringWithFormat:@"%@", response];
    NSString *myerror = [NSString stringWithFormat:@"%@", error];

    NSLog(@"%@", myresponse);
    NSLog(@"%@", myerror);
}] resume];

任何建议将不胜感激!

4

3 回答 3

1

问题不是 ATS,问题是当您向https://gateway.boramash.com/发出 GET 请求时收到的 SSL 证书无效...

要在不替换后端证书的情况下通过此操作,您需要实现以下委托方法:

- (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential *))completionHandler;

这是一个例子:

- (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential * _Nullable))completionHandler {
    if([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust])
    {
        NSString *host = challenge.protectionSpace.host;
        NSArray *acceptedDomains = @[@".boramash.com$"];
        BOOL accept = NO;

        for (NSString *pattern in acceptedDomains)
        {
            NSRange range = [host rangeOfString:pattern options:NSCaseInsensitiveSearch|NSRegularExpressionSearch];
            if (range.location != NSNotFound)
            {
                accept = YES;
                break;
            }
        }

        if (accept)
        {
            NSLog(@"%@", [NSString stringWithFormat:@"WARNING: accepting an invalid certificate from host: %@", host]);
            NSURLCredential *credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];
            completionHandler(NSURLSessionAuthChallengeUseCredential, credential);
        }
        else
        {
            NSLog(@"%@", [NSString stringWithFormat:@"WARNING: discarding an invalid certificate from host: %@", host]);
        }
    }
}
于 2016-01-25T22:23:48.357 回答
1

TL;DR:出于某种原因,您的服务器没有(总是?)发送中间证书。检查您的服务器配置和证书/中间证书格式(检查日志中的错误,并检查服务器是否已正确重新启动)。

您可以在命令行上使用openssl s_client -connect gateway.boramash.com:443.

它目前返回:

depth=0 CN = gateway.boramash.com
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=0 CN = gateway.boramash.com
verify error:num=21:unable to verify the first certificate
verify return:1
---
Certificate chain
 0 s:/CN=gateway.boramash.com
   i:/C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X1

...

    Verify return code: 21 (unable to verify the first certificate)

这意味着它找不到证书来验证证书上的签名。

您希望它返回:

depth=2 O = Digital Signature Trust Co., CN = DST Root CA X3
verify return:1
depth=1 C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X1
verify return:1
depth=0 CN = gateway.boramash.com
verify return:1
---
Certificate chain
 0 s:/CN=gateway.boramash.com
   i:/C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X1

...

    Verify return code: 0 (ok)

(这是通过下载中间证书并将其提供给 openssl 来获得的-CAfile lets-encrypt-x1-cross-signed.pem)。

您还可以通过添加来验证中间证书确实没有发送-showcerts

奇怪的是它在 Safari 中确实有效(对我来说),尽管它在 Firefox 中无效。不太确定有什么区别(可能中间证书是从另一个请求缓存到使用来自同一 CA 的证书的正确配置的服务器),但请仔细检查您的服务器配置(以及证书文件的格式),直到 openssl 喜欢它,iOS 也应该喜欢它。

于 2016-01-25T23:58:39.053 回答
0

尝试添加NSExceptionAllowsInsecureHTTPLoads并设置true

于 2016-01-25T22:17:46.910 回答