gpt4 book ai didi

ios - iOS UIWebView 上的客户端证书身份验证适用于 iOS 6.1 但不适用于 iOS 7

转载 作者:可可西里 更新时间:2023-11-01 04:44:05 26 4
gpt4 key购买 nike

我正在尝试使用客户端证书身份验证来访问安全网站。我使用的代码在 iOS 6.1 中运行良好,但在使用 iOS 7 时服务器返回 403.7 错误时失败。

我使用 connection:willSendRequestForAuthenticationChallenge 处理程序来检查身份验证方法并提供客户端证书。

我的代码是:

- (void)connection: (NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{

if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust])
{
NSLog(@"Trust Challenge");
SecTrustResultType trustResultType;
OSStatus err = SecTrustEvaluate(challenge.protectionSpace.serverTrust, &trustResultType);

NSLog(@"SecTrustResult %u %d",trustResultType, (int)err);

if (trustResultType == kSecTrustResultProceed || trustResultType == kSecTrustResultConfirm || trustResultType == kSecTrustResultUnspecified) {
[challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust] forAuthenticationChallenge:challenge];
}
else{
[challenge.sender cancelAuthenticationChallenge:challenge];
}

} else {
NSString *path = [[NSBundle mainBundle]pathForResource:@"mycert" ofType:@"pfx"];
NSData *p12data = [NSData dataWithContentsOfFile:path];

CFDataRef inP12data = (__bridge CFDataRef)p12data;

SecIdentityRef myIdentity;
SecTrustRef myTrust;
extractIdentityAndTrust(inP12data, &myIdentity, &myTrust);
assert(myIdentity != nil);
assert(myTrust != nil);

long count = SecTrustGetCertificateCount(myTrust);
NSMutableArray* myCertificates = nil;
if(count > 1) {
myCertificates = [NSMutableArray arrayWithCapacity:count];
for(int i = 1; i < count; ++i) {
[myCertificates addObject:(__bridge id)SecTrustGetCertificateAtIndex(myTrust, i)];
}
}

NSURLCredential *credential = [NSURLCredential credentialWithIdentity:myIdentity certificates:myCertificates persistence:NSURLCredentialPersistenceNone];
assert(credential != nil);

NSLog(@"User: %@, certificates %@ identity:%@", [credential user], [credential certificates], [credential identity]);
[[challenge sender] useCredential:credential forAuthenticationChallenge:challenge];
}
}

我使用这个函数来提取证书的内容:

OSStatus extractIdentityAndTrust(CFDataRef inP12data, SecIdentityRef *identity, SecTrustRef *trust)
{
OSStatus securityError = errSecSuccess;

CFStringRef password = CFSTR("password");
const void *keys[] = { kSecImportExportPassphrase };
const void *values[] = { password };

CFDictionaryRef options = CFDictionaryCreate(NULL, keys, values, 1, NULL, NULL);

CFArrayRef items = CFArrayCreate(NULL, 0, 0, NULL);
securityError = SecPKCS12Import(inP12data, options, &items);

if (securityError == 0) {
CFDictionaryRef myIdentityAndTrust = CFArrayGetValueAtIndex(items, 0);
const void *tempIdentity = NULL;
tempIdentity = CFDictionaryGetValue(myIdentityAndTrust, kSecImportItemIdentity);
*identity = (SecIdentityRef)tempIdentity;
const void *tempTrust = NULL;
tempTrust = CFDictionaryGetValue(myIdentityAndTrust, kSecImportItemTrust);
*trust = (SecTrustRef)tempTrust;

CFIndex count = CFArrayGetCount(items);
NSLog(@"Certificates found: %ld",count);
}

if (options) {
CFRelease(options);
}

return securityError;
}

mycert.pfx 文件包含中间证书和客户端证书。

永远不会调用 connection:didFailWithError 函数。

-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
NSLog(@"Error: %@", [error userInfo]);
}

所以看起来证书协商在某种程度上是成功的。

我的问题类似于SSL - behaves differently in iOS7?但我使用的是带有 IIS 7.5 的 Windows Server 2008 R2。已在服务器上启用 TLS 1.1 和 TLS 1.2 协议(protocol)。

WireShark 跟踪显示使用 iOS 7 时 TLS 握手期间的证书框架为空。使用 iOS 6.1 时发送并验证证书。

我可以使用 Safari 在 iOS 7 中访问该网站。

非常感谢任何帮助。

最佳答案

在 Apple Developer 支持的帮助下,我找到了解决方案。该解决方案涉及创建自定义 NSURLProtocol。我在 https://developer.apple.com/library/ios/#samplecode/CustomHTTPProtocol/ 使用了 Apple 示例代码.示例代码展示了如何覆盖 HTTPS 服务器信任评估,因此需要对其进行修改以使用客户端证书身份验证。

我修改了 AppDelegate didRecieveAuthenticationChallenge 函数。

- (void)customHTTPProtocol:(CustomHTTPProtocol *)protocol didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
// A CustomHTTPProtocol delegate callback, called when the protocol has an authenticate
// challenge that the delegate accepts via - customHTTPProtocol:canAuthenticateAgainstProtectionSpace:.
// In this specific case it's only called to handle server trust authentication challenges.
// It evaluates the trust based on both the global set of trusted anchors and the list of trusted
// anchors returned by the CredentialsManager.
{
OSStatus err;
NSURLCredential * credential;

assert(protocol != nil);
assert(challenge != nil);

credential = nil;

// Handle ServerTrust and Client Certificate challenges

NSString *authenticationMethod = [[challenge protectionSpace] authenticationMethod];
if ([authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
NSLog(@"Trust Challange");
SecTrustResultType trustResultType;
err = SecTrustEvaluate(challenge.protectionSpace.serverTrust, &trustResultType);

NSLog(@"SecTrustResult %u %d",trustResultType, (int)err);

if (trustResultType == kSecTrustResultProceed || trustResultType == kSecTrustResultUnspecified) {
credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];
assert(credential != nil);
}
} else {
NSString *path = [[NSBundle mainBundle]pathForResource:@"mycert" ofType:@"pfx"];
NSData *p12data = [NSData dataWithContentsOfFile:path];

SecIdentityRef identity = NULL;
SecCertificateRef certificate = NULL;

[Util identity:&identity andCertificate:&certificate fromPKCS12Data:p12data withPassphrase:@"asia1215"];

assert(identity != NULL);

NSArray *certArray = [NSArray arrayWithObject:(__bridge id)certificate];
credential = [NSURLCredential credentialWithIdentity:identity certificates:certArray persistence:NSURLCredentialPersistencePermanent];
}

[protocol resolveAuthenticationChallenge:challenge withCredential:credential];
}

关于ios - iOS UIWebView 上的客户端证书身份验证适用于 iOS 6.1 但不适用于 iOS 7,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21287596/

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