私のサーバーは自己署名入りのSSL証明書を使用しています。そして、私が何をしても、iOSはそれらを受け入れたくありません。これは私のコードです:NSURLSessionAuthChallengeUseCredentialは役に立ちません。 iOSを自分のサーバーに信頼させる方法
- (void)URLSession:(NSURLSession *)session
didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge
completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition,
NSURLCredential *credential))completionHandler
{
NSString* authenticationMethod = challenge.protectionSpace.authenticationMethod;
if (![authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust])
{
completionHandler(NSURLSessionAuthChallengePerformDefaultHandling, nil);
return;
}
SecTrustRef trust = challenge.protectionSpace.serverTrust;
CFIndex count = SecTrustGetCertificateCount(trust);
CFMutableArrayRef originalCertificates = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
for (CFIndex i = 0; i < count; i++)
{
SecCertificateRef certRef = SecTrustGetCertificateAtIndex(trust, i);
CFArrayAppendValue(originalCertificates, certRef);
CFStringRef certSummary = SecCertificateCopySubjectSummary(certRef);
NSLog(@"CERT %ld %@", i, certSummary);
}
//SecPolicyRef policyRef = SecPolicyCreateSSL(true, CFSTR("192.168.50.80"));
SecPolicyRef policyRef = SecPolicyCreateBasicX509();
SecTrustRef newTrust;
OSStatus status = SecTrustCreateWithCertificates(originalCertificates, policyRef, & newTrust);
assert(status == noErr);
NSString* path = [[NSBundle mainBundle] pathForResource:@"no1bcCA" ofType:@"der"];
NSData* data = [NSData dataWithContentsOfFile:path];
SecCertificateRef cert = SecCertificateCreateWithData(NULL, (CFDataRef) data);
assert(cert);
NSString* rootPath = [[NSBundle mainBundle] pathForResource:@"no1bcRootCA" ofType:@"der"];
NSData* rootData = [NSData dataWithContentsOfFile:rootPath];
SecCertificateRef rootCert = SecCertificateCreateWithData(NULL, (CFDataRef) rootData);
assert(rootCert);
SecTrustSetAnchorCertificates(newTrust, (CFArrayRef)@[(__bridge id)rootCert, (__bridge id)cert]);
SecTrustSetAnchorCertificatesOnly(newTrust, NO);
SecTrustResultType trustResult;
SecTrustEvaluate(newTrust, &trustResult);
if (trustResult == kSecTrustResultUnspecified || trustResult == kSecTrustResultProceed)
{
NSURLCredential* credential = [NSURLCredential credentialForTrust:newTrust];
completionHandler(NSURLSessionAuthChallengeUseCredential, credential);
}
else
{
completionHandler(NSURLSessionAuthChallengePerformDefaultHandling, nil);
}
}
のでtrustResult
はkSecTrustResultUnspecified
ですが、私のNSURLSessionDataTask
の完了ハンドラに私はまだ、次のエラーが表示さ:私は回復の提案を愛する
Error Domain=NSURLErrorDomain Code=-1200 "An SSL error has occurred and a secure connection to the server cannot be made." UserInfo={NSURLErrorFailingURLPeerTrustErrorKey=<SecTrustRef: 0x6000003040b0>, NSLocalizedRecoverySuggestion=Would you like to connect to the server anyway?, _kCFStreamErrorDomainKey=3, _kCFStreamErrorCodeKey=-9802, NSErrorPeerCertificateChainKey=(
"<cert(0x7f81ef80ca00) s: sems.no1bc.local i: no1bcCA>",
"<cert(0x7f81ef80d400) s: no1bcCA i: no1bcRootCA>",
"<cert(0x7f81ef82b800) s: no1bcRootCA i: no1bcRootCA>"
), NSUnderlyingError=0x604000255030 {Error Domain=kCFErrorDomainCFNetwork Code=-1200 "(null)" UserInfo={_kCFStreamPropertySSLClientCertificateState=0, kCFStreamPropertySSLPeerTrust=<SecTrustRef: 0x6000003040b0>, _kCFNetworkCFStreamSSLErrorOriginalValue=-9802, _kCFStreamErrorDomainKey=3, _kCFStreamErrorCodeKey=-9802, kCFStreamPropertySSLPeerCertificates=(
"<cert(0x7f81ef80ca00) s: sems.no1bc.local i: no1bcCA>",
"<cert(0x7f81ef80d400) s: no1bcCA i: no1bcRootCA>",
"<cert(0x7f81ef82b800) s: no1bcRootCA i: no1bcRootCA>"
)}}, NSLocalizedDescription=An SSL error has occurred and a secure connection to the server cannot be made., NSErrorFailingURLKey=https://192.168.50.80/pgpuniversaldesktop, NSErrorFailingURLStringKey=https://192.168.50.80/pgpuniversaldesktop, NSErrorClientCertificateStateKey=0}
を。それは
Would you like to connect to the server anyway?
はい、私は言うでしょうか?私は何をしますか?
<key>NSAppTransportSecurity</key>
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>192.168.50.80</key>
<dict>
<key>NSIncludesSubdomains</key>
<true/>
<key>NSExceptionAllowsInsecureHTTPLoads</key>
<true/>
<key>NSExceptionMinimumTLSVersion</key>
<string>TLSv1.2</string>
<key>NSExceptionRequiresForwardSecrecy</key>
<false/>
<key>NSRequiresCertificateTransparency</key>
<false/>
</dict>
</dict>
</dict>
それが助けたことがない:
別に私もATSでプレイしようとしたことすべてから、これは私がplistファイルに入れものです。だから、私は明示的にiOSに言っています:「このサーバを信頼し、信頼してください。」しかし、そうはしません。理由は何でしょうか?システムを強制的にサーバーを信頼させるにはどうすればよいですか?とにかく私はどうしたらサーバーに接続するのですか?
Macアプリケーションからこのコードを実行すると問題なく動作するのは面白いです。しかし、iOSで動作しない