导入p12证书,可以完全访问我的应用程序的私钥(OS X)

时间:2016-06-30 14:42:08

标签: iphone xcode macos certificate keychain

我正在使用mac app中的证书身份验证访问https网络服务器,因此我需要处理身份验证并提供我的证书(URLSession - > NSURLAuthenticationMethodClientCertificate - >调用SecPKCS12Import并从导入的证书中提取身份 - >从中创建NSURLCredential身份并在completionHandler中将其提供给服务器。)

但是在每次https请求之后,会显示“MYAPP想要在你的钥匙串中使用”privateKey“签名的对话框:

enter image description here

我想避免这个消息。我的应用已正确签名。我想我需要在导入时设置证书的访问权限(我的应用程序的完全访问权限),我正在尝试使用SecAccessCreate和SecPKCS12Import选项:

func extractIdentity(certData:NSData, certPassword:String) -> IdentityAndTrust {

        var identityAndTrust:IdentityAndTrust!
        var securityError:OSStatus = errSecSuccess

        var items:CFArray?
        //let certOptions:CFDictionary = [ kSecImportExportPassphrase.takeRetainedValue() as String: certPassword ];

        let index: CFIndex = 2

        let passwordKey = kSecImportExportPassphrase as String;
        let passwordValue: CFString = "PASSWORD";

        let accessKey = kSecImportExportAccess as String;
        var access:SecAccessRef? = nil;
        SecAccessCreate("CERTIFICATE_NAME", nil, &access);

        var keys = [unsafeAddressOf(accessKey), unsafeAddressOf(passwordKey)]
        var values = [unsafeAddressOf(access!), unsafeAddressOf(passwordValue)]

        var keyCallbacks = kCFTypeDictionaryKeyCallBacks
        var valueCallbacks = kCFTypeDictionaryValueCallBacks

        let options = CFDictionaryCreate(kCFAllocatorDefault, &keys, &values, index, &keyCallbacks, &valueCallbacks)

        // import certificate to read its entries
        securityError = SecPKCS12Import(certData, options, &items);

        if securityError == errSecSuccess {

            let certItems:CFArray = items as CFArray!;
            let certItemsArray:Array = certItems as Array
            let dict:AnyObject? = certItemsArray.first;

            if let certEntry:Dictionary = dict as? Dictionary<String, AnyObject> {

                // grab the identity
                let identityPointer:AnyObject? = certEntry["identity"];
                let secIdentityRef:SecIdentityRef = identityPointer as! SecIdentityRef!;

                // grab the trust
                let trustPointer:AnyObject? = certEntry["trust"];
                let trustRef:SecTrustRef = trustPointer as! SecTrustRef;

                // grab the certificate chain
                var certRef:SecCertificate?
                SecIdentityCopyCertificate(secIdentityRef, &certRef);
                let certArray:NSMutableArray = NSMutableArray();
                certArray.addObject(certRef as SecCertificateRef!);

                identityAndTrust = IdentityAndTrust(identityRef: secIdentityRef, trust: trustRef, certArray: certArray);
            }
        }

        return identityAndTrust;
    }

无论如何它不起作用。如何避免此对话框?

此线程How do I add authorizations to code sign an app from new keychain without any human interaction与使用“security”命令导入证书有关,建议在导入证书时使用-A或-T标志,但是我可以在没有控制台命令的情况下以编程方式执行吗?

1 个答案:

答案 0 :(得分:1)

您可能需要多次构建和运行应用程序,这意味着第一次将证书添加到密钥链中,并且执行该证书的可执行文件被授权使用私钥。但是,当您进行一些更改并重建项目时,可执行文件已被替换,新的可执行文件无法访问私钥(当用户必须更新软件或因任何原因重新安装时,这也是一个问题)

我发现我必须做的是在使用后从钥匙链中删除证书,并在每次使用前重新添加。但是,我已经知道您可以授予应用程序标识符权限,以便在您的情况下也可以使用。

我在问题的答案中有一个代码示例:How do I kill the popup?