【问题标题】:Loading a X509 pem certificate with password. Objective C加载带有密码的 X509 pem 证书。目标 C
【发布时间】:2016-10-19 08:31:01
【问题描述】:

我是 Objective-c 和 iOS 编程的新手。

我需要使用 REST API,其中请求需要使用 x509 PEM 证书文件和证书密码进行双向 SSL 身份验证。

我的问题是我真的不知道如何在目标 C 中做到这一点,在 C# 中它会很简单:

X509Certificate2 myCertificate = new x509Certificate2(certificatePath, certificatePassword);
myRequest.ClientCertificate.Add(myCertificate);

其中"myRequest"只是代表http请求的变量。

我已经在许多论坛和帖子中寻找了一段时间,包括一些旧的 stackoverflow 问题。 人们给出的主要提示是“使用 OpenSSL”,但我在少数地方(我认为即使是在 stackoverflow 问题中)读到 Apple 已弃用 OpenSSL。

问题:我如何加载 .pem x509 证书及其密码,以使用 Objective-C 语言将 POST 请求发送到外部 REST API 服务?

谢谢。

【问题讨论】:

    标签: ios objective-c x509


    【解决方案1】:

    我自己的解决方案:

    使用 OpenSSL 命令转换 .pem 文件介绍 pkcs12 证书:

    openssl pkcs12 -export -in "certificateFile" -inkey "KeyFile" -out "certificate.p12"
    

    然后设置本教程中的一些代码:https://vanjakom.wordpress.com/tag/nsurlconnection/

    基本上:

    - (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
    {
        NSLog(@"Authentication challenge");
    
        // load cert
        NSString *path = [[NSBundle mainBundle] pathForResource:@"userA" ofType:@"p12"];
        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];
    }
    

    OSStatus extractIdentityAndTrust(CFDataRef inP12data, SecIdentityRef *identity, SecTrustRef *trust)
    {
        OSStatus securityError = errSecSuccess;
    
        CFStringRef password = CFSTR("userA");
        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;
    }
    

    “从教程中复制的代码,没有复制我自己的修改以满足我自己的需要”。

    解决了

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-08-15
      • 2012-05-01
      • 1970-01-01
      • 2020-09-30
      • 2012-01-22
      • 2018-08-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多