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

标签 iphone xcode macos certificate keychain

我正在从 mac 应用程序使用证书身份验证访问 https Web 服务器,因此我需要处理身份验证并提供我的证书(URLSession -> NSURLAuthenticationMethodClientCertificate -> 调用 SecPKCS12Import 并从导入的证书中提取身份 -> 从身份创建 NSURLCredential 并提供它在completionHandler 中发送到服务器)。

但每次 https 请求后,都会显示对话框“MYAPP 希望使用钥匙串(keychain)中的“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 标志,但我可以在没有控制台命令的情况下以编程方式执行此操作吗?

最佳答案

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

我发现我必须做的是在使用后从钥匙串(keychain)中删除证书,并在每次使用前重新添加它。不过,我了解到您可以向应用程序标识符授予权限,这样这也适用于您的情况。

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

关于iphone - 导入 p12 证书,可以完全访问我的应用程序的私钥 (OS X),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38126462/

相关文章:

新 map 应用程序中的 iPhone map 折叠按钮

iphone - UIAlertView问题

ios - 在自定义 .plist 文件中使用用户定义的build设置

c++ - Xcode:单例实现错误: "Redefinition of class"

iphone - 如何在 iphone 应用程序中将音频文件上传到服务器?

iphone - 在启用 arc 的应用程序中重构 #ifndef __OBJC_GC_

c++ - 在 Xcode 6.3 中使用 Boost C++?

Swift - 为什么 NSOutlineView 中的参数项总是 nil?

c++ - clion cmake 项目不编译 : dyld mach-o, 但为模拟器(不是 macOS)构建

swift - 绑定(bind)到 SwiftUI Mac 应用程序中的结构体属性