gpt4 book ai didi

ios - SecTrustEvaluate 总是返回 kSecTrustResultRecoverableTrustFailure

转载 作者:太空宇宙 更新时间:2023-11-03 14:06:39 25 4
gpt4 key购买 nike

我想使用 afnetworking 实现 tls 自签名连接。我有一个 p12 和 der 文件尝试评估自签名证书的服务器信任证书,使用相同的证书文件 android 客户端连接成功,经过大量研究我仍然无法解决。任何人都可以帮助我。这是我的完整代码

- (void)sendRequest{
// Do any additional setup after loading the view, typically from a nib.
NSURL * actionURL=[[NSURL alloc] initWithString:@"https://38.121.62.19"];
NSURL * relativeURL=[[NSURL alloc] initWithString:@"/"];
NSString *cerPath = [[NSBundle mainBundle] pathForResource:@"server" ofType:@"der"];
NSData *certData = [NSData dataWithContentsOfFile:cerPath];

AFSecurityPolicy *securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate];
[securityPolicy setPinnedCertificates:[[NSSet alloc] initWithObjects:certData, nil]];
[securityPolicy setAllowInvalidCertificates:kAllowsInvalidSSLCertificate];
[securityPolicy setValidatesDomainName:NO];
AFHTTPSessionManager *manager = [[AFHTTPSessionManager alloc] initWithBaseURL:actionURL];
[manager setSecurityPolicy:securityPolicy];
manager.responseSerializer=[AFHTTPResponseSerializer serializer];
[manager GET:relativeURL.absoluteString parameters:nil progress:nil success:^(NSURLSessionTask *task, id responseObject) {
NSLog(@"Success");

} failure:^(NSURLSessionTask *operation, NSError *error) {
NSLog(@"Error: %@", error);
}];
// [manager setTaskDidReceiveAuthenticationChallengeBlock:^NSURLSessionAuthChallengeDisposition(NSURLSession * _Nonnull session, NSURLSessionTask * _Nonnull task, NSURLAuthenticationChallenge * _Nonnull challenge, NSURLCredential *__autoreleasing _Nullable * _Nullable credential) {

[manager setSessionDidReceiveAuthenticationChallengeBlock:^NSURLSessionAuthChallengeDisposition(NSURLSession * _Nonnull session, NSURLAuthenticationChallenge * _Nonnull challenge, NSURLCredential *__autoreleasing _Nullable * _Nullable credential) {
if ([challenge previousFailureCount] > 0) {
//this will cause an authentication failure
[[challenge sender] cancelAuthenticationChallenge:challenge];
NSLog(@"Bad Username Or Password");
return NSURLSessionAuthChallengeUseCredential;
}
//this is checking the server certificate
if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
SecTrustResultType result;
//This takes the serverTrust object and checkes it against your keychain
SecTrustEvaluate(challenge.protectionSpace.serverTrust, &result);


//if we want to ignore invalid server for certificates, we just accept the server
if (kAllowsInvalidSSLCertificate) {
NSData *rootCertData = [NSData dataWithContentsOfFile: [[NSBundle mainBundle] pathForResource:@"server" ofType:@"der"]];
CFDataRef myCertData = (__bridge CFDataRef)rootCertData;
SecCertificateRef rootCertRef = SecCertificateCreateWithData(NULL, (CFDataRef) myCertData);
SecTrustRef trust = [[challenge protectionSpace] serverTrust]; // Create trust object
NSArray *trustArray = [NSArray arrayWithObjects:(__bridge id _Nonnull)(rootCertRef), nil]; // Add as many certificates as needed

SecTrustSetAnchorCertificates(trust, (CFArrayRef) trustArray );
SecTrustSetAnchorCertificatesOnly(trust, YES);
SecTrustResultType trustResult; // Store trust result in this
SecTrustEvaluate(trust, &trustResult);
SecTrustResultType result1;

[challenge.sender useCredential:[NSURLCredential credentialForTrust: trust] forAuthenticationChallenge: challenge];
return NSURLSessionAuthChallengeUseCredential;

} else if(result == kSecTrustResultProceed || result == kSecTrustResultUnspecified) {
//When testing this against a trusted server I got kSecTrustResultUnspecified every time. But the other two match the description of a trusted server
[challenge.sender useCredential:[NSURLCredential credentialForTrust: challenge.protectionSpace.serverTrust] forAuthenticationChallenge: challenge];
return NSURLSessionAuthChallengeUseCredential;

}
} else if ([[challenge protectionSpace] authenticationMethod] == NSURLAuthenticationMethodClientCertificate) {
//this handles authenticating the client certificate

/*
What we need to do here is get the certificate and an an identity so we can do this:
NSURLCredential *credential = [NSURLCredential credentialWithIdentity:identity certificates:myCerts persistence:NSURLCredentialPersistencePermanent];
[[challenge sender] useCredential:credential forAuthenticationChallenge:challenge];

It's easy to load the certificate using the code in -installCertificate
It's more difficult to get the identity.
We can get it from a .p12 file, but you need a passphrase:
*/

NSData *p12Data = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"client" ofType:@"p12"]];

CFStringRef password = CFSTR("123456");
const void *keys[] = { kSecImportExportPassphrase };
const void *values[] = { password };
CFDictionaryRef optionsDictionary = CFDictionaryCreate(NULL, keys, values, 1, NULL, NULL);
CFArrayRef p12Items;

OSStatus result = SecPKCS12Import((__bridge CFDataRef)p12Data, optionsDictionary, &p12Items);

if(result == noErr) {
CFDictionaryRef identityDict = CFArrayGetValueAtIndex(p12Items, 0);
SecIdentityRef identityApp =(SecIdentityRef)CFDictionaryGetValue(identityDict,kSecImportItemIdentity);

SecCertificateRef certRef;
SecIdentityCopyCertificate(identityApp, &certRef);

SecCertificateRef certArray[1] = { certRef };
CFArrayRef myCerts = CFArrayCreate(NULL, (void *)certArray, 1, NULL);
CFRelease(certRef);

NSURLCredential *credential = [NSURLCredential credentialWithIdentity:identityApp certificates:(__bridge NSArray *)myCerts persistence:NSURLCredentialPersistencePermanent];
CFRelease(myCerts);

[[challenge sender] useCredential:credential forAuthenticationChallenge:challenge];
} else {
[[challenge sender] cancelAuthenticationChallenge:challenge];
}
} else if ([[challenge protectionSpace] authenticationMethod] == NSURLAuthenticationMethodDefault || [[challenge protectionSpace] authenticationMethod] == NSURLAuthenticationMethodNTLM) {

// For normal authentication based on username and password. This could be NTLM or Default.
/*
DAVCredentials *cred = _parentSession.credentials;
NSURLCredential *credential = [NSURLCredential credentialWithUser:cred.username password:cred.password persistence:NSURLCredentialPersistenceForSession];
[[challenge sender] useCredential:credential forAuthenticationChallenge:challenge];
*/

NSLog(@"BASIC AUTHENTICATION");

} else {
//If everything fails, we cancel the challenge.
[[challenge sender] cancelAuthenticationChallenge:challenge];
}
return NSURLSessionAuthChallengePerformDefaultHandling;

}];

最佳答案

如果您调用方法 setSessionDidReceiveAuthenticationChallengeBlockAFSecurityPolicy 将不起作用。这是 AFNetworking

中的代码
- (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *credential))completionHandler
{
NSURLSessionAuthChallengeDisposition disposition = NSURLSessionAuthChallengePerformDefaultHandling;
__block NSURLCredential *credential = nil;

if (self.sessionDidReceiveAuthenticationChallenge) {
disposition = self.sessionDidReceiveAuthenticationChallenge(session, challenge, &credential);
} else {
if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
if ([self.securityPolicy evaluateServerTrust:challenge.protectionSpace.serverTrust forDomain:challenge.protectionSpace.host]) {
credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];
if (credential) {
disposition = NSURLSessionAuthChallengeUseCredential;
} else {
disposition = NSURLSessionAuthChallengePerformDefaultHandling;
}
} else {
disposition = NSURLSessionAuthChallengeCancelAuthenticationChallenge;
}
} else {
disposition = NSURLSessionAuthChallengePerformDefaultHandling;
}
}

if (completionHandler) {
completionHandler(disposition, credential);
}
}

AFSecurityPolicysessionDidReceiveAuthenticationChallenge 不会一起工作。您不需要配置 AFSecurityPolicy 的实例。
您可以按如下方式更改您的服务器信任代码:

    if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
if (kAllowsInvalidSSLCertificate) {
NSData *rootCertData = [NSData dataWithContentsOfFile: [[NSBundle mainBundle] pathForResource:@"server" ofType:@"der"]];
CFDataRef myCertData = (__bridge CFDataRef)rootCertData;
SecCertificateRef rootCertRef = SecCertificateCreateWithData(NULL, (CFDataRef) myCertData);
SecTrustRef trust = [[challenge protectionSpace] serverTrust]; // Create trust object
NSArray *trustArray = [NSArray arrayWithObjects:(__bridge id _Nonnull)(rootCertRef), nil]; // Add as many certificates as needed

SecTrustSetAnchorCertificates(trust, (CFArrayRef) trustArray );
SecTrustSetAnchorCertificatesOnly(trust, YES);
SecTrustResultType trustResult; // Store trust result in this
SecTrustEvaluate(trust, &trustResult);

BOOL certificateIsValid = (trustResult == kSecTrustResultUnspecified || trustResult == kSecTrustResultProceed);
if (certificateIsValid) {
*credential = [NSURLCredential credentialForTrust:trust];
return NSURLSessionAuthChallengeUseCredential;
} else {
return NSURLSessionAuthChallengePerformDefaultHandling;
}
}
}

关于ios - SecTrustEvaluate 总是返回 kSecTrustResultRecoverableTrustFailure,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40120628/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com