【问题标题】:Call to SOAP WebService using client certificate in objective c在目标 c 中使用客户端证书调用 SOAP WebService
【发布时间】:2015-06-03 09:49:43
【问题描述】:

我是一名非常初级的目标 C 开发人员,我正在尝试调用需要客户端证书的 SOAP Web 服务。

我进行了 SOAP 调用,但服务器返回我需要证书。

我有一个.p12 文件(证书),我已将它保存在我的钥匙串上,因此我可以从我的浏览器访问,但我不知道如何在我正在尝试的应用程序上使用此文件建造。我在 Google 上搜索过,但找不到任何有效的答案。

有什么线索吗?提前致谢。

【问题讨论】:

  • 谁否决了这个问题?为什么?最重要的是:¿有人可以帮助我吗?我仍然坚持下去。

标签: objective-c web-services ssl soap client-certificates


【解决方案1】:

我会回答我自己的问题,因为没有人回答,而且我已经找到了解决方案。

首先,您需要将证书保存在项目目录中。将证书从其文件夹拖放到 Xcode 中项目的目录中。选择“复制”,然后对将出现的窗口选择“是”。

然后,您需要让您的项目识别该文件。

目标 > 构建阶段 > 复制捆绑资源。并在此处添加文件。

回到你打电话的班级:

-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
    [webData appendData:data];
}
-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
    NSLog(@"ERROR with theConenction");
    [connection release];
    [webData release];
}

-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
    NSLog(@"DONE. Received Bytes: %lu", (unsigned long)[webData length]);
    NSString *theXML = [[NSString alloc] initWithBytes: [webData mutableBytes] length:[webData length] encoding:NSUTF8StringEncoding];//NSUTF8StringEncoding NSASCIIStringEncoding
    NSLog(@"%@",theXML);
    [theXML release];
}

- (OSStatus)extractIdentity:(CFDataRef)inP12Data :(SecIdentityRef*)identity {
    OSStatus securityError = errSecSuccess;

    CFStringRef password = CFSTR("passwd");
    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 ident = CFArrayGetValueAtIndex(items,0);
        const void *tempIdentity = NULL;
        tempIdentity = CFDictionaryGetValue(ident, kSecImportItemIdentity);
        *identity = (SecIdentityRef)tempIdentity;
    }

    if (options) {
        CFRelease(options);
    }

    return securityError;
}


- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace
{
    return YES;
}

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

    CFStringRef password = CFSTR("passwd");
    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;
    }

    if (options) {
        CFRelease(options);
    }

    return securityError;
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
    NSLog(@"Authentication challenge");

    // load cert
    NSString *path = [[NSBundle mainBundle] pathForResource:@"nameOfFile" ofType:@"p12"];// If it's not working Targets > Build phases > Copy bundle Resources
    NSData *p12data = [NSData dataWithContentsOfFile:path];
    CFDataRef inP12data = (__bridge CFDataRef)p12data;

    SecIdentityRef myIdentity;
    SecTrustRef myTrust;
    OSStatus status = extractIdentityAndTrust(inP12data, &myIdentity, &myTrust);

    SecCertificateRef myCertificate;
    SecIdentityCopyCertificate(myIdentity, &myCertificate);
    const void *certs[] = { myCertificate };
    CFArrayRef certsArray = CFArrayCreate(NULL, certs, 1, NULL);

    NSURLCredential *credential = [NSURLCredential credentialWithIdentity:myIdentity certificates:(__bridge NSArray*)certsArray persistence:NSURLCredentialPersistencePermanent];

    [[challenge sender] useCredential:credential forAuthenticationChallenge:challenge];
}

然后跑!

【讨论】:

    猜你喜欢
    • 2010-09-16
    • 1970-01-01
    • 2015-05-03
    • 2019-01-04
    • 2011-05-16
    • 2015-11-11
    • 2010-10-30
    • 1970-01-01
    • 2012-04-27
    相关资源
    最近更新 更多