Macos 如何允许所有应用程序在没有提示的情况下访问keychain项
Macos 如何允许所有应用程序在没有提示的情况下访问keychain项,macos,keychain,Macos,Keychain,钥匙链访问中有一个选项,允许所有应用程序无限制地访问钥匙链项目。 我不知道如何以编程方式设置它。我已尝试使用空ACL创建并设置新的SecAccessRef,但实际上没有任何更改(使用SecItemUpdate更新kSecAttrAccess)。我还尝试获取项目所有授权标记的所有ACL列表,并将ACL内容设置为该ACL/标记组合的空数组。我可以清除允许的应用程序列表,但这不允许所有应用程序无限制地访问该项目。我看不到一种使用keychainAPI设置的方法 因此,我的问题是如何操纵Access对
钥匙链访问
中有一个选项,允许所有应用程序无限制地访问钥匙链项目。
我不知道如何以编程方式设置它。我已尝试使用空ACL创建并设置新的SecAccessRef,但实际上没有任何更改(使用SecItemUpdate
更新kSecAttrAccess
)。我还尝试获取项目所有授权标记的所有ACL列表,并将ACL内容设置为该ACL/标记组合的空数组。我可以清除允许的应用程序列表,但这不允许所有应用程序无限制地访问该项目。我看不到一种使用keychainAPI设置的方法
因此,我的问题是如何操纵Access对象或其ACL,以允许对密钥链项进行不受限制的访问或至少进行不受限制的读取?根据我的经验,安全API中最新的“便利”方法将项存放到密钥链中:
SecKeychainAddGenericPassword()
SecKeychainAddInternetPassword()
SecKeyGeneratePair()
change\u acl
authorization acl条目-这意味着没有用户提示,任何应用程序随后都无法修改acl
因此,一般来说,在没有用户提示的情况下,似乎无法修改大多数现有密钥链项目上的ACL
但是,如果您使用较旧的安全API方法将项目添加到密钥链(您可以提供自己创建的SecAccessRef
):
SecKeychainItemCreateFromContent()
(在中不推荐使用 OS X 10.7,但仍能正常工作)SecKeyCreatePair()
SecAccessCreate()
或secaccesscreatewithowner()创建一个SecAccessRef
SecACLCreateWithSimpleContents()向SecAccessRef
添加一个ACL,该ACL具有任何
授权、无提示行为(SecKeychainPromptSelector=0
)和一个NULL
受信任的应用程序列表
SecAccessRef
,以实现“允许所有应用程序访问此项目”虽然Apple文档中似乎缺少这一点,但提供给
SecKeyGeneratePair()
的参数字典可以有一个键kSecAttrAccess
和相关值,该值是提供所需ACL的SecAccessRef
。在初始生成时提供此功能将允许在没有用户提示的情况下设置ACL。正如@mike-c在其回答中所述,似乎无法使用最初为支持iOS和iCloud而引入的较新的Keychain API来实现此解决方案。尤其是访问控制API不再与macOS最初处理它的方式兼容。除此之外还引入了大量不同的API,如(09:40)所示,这使得理解更加困难
@mike-c的答案包含了很多提示,但并没有显示全部情况。与苹果开发者论坛上的类似,它告诉我们,必须在创建时设置钥匙链项目的适当访问控制。有点遗憾的是,新文档a中不再提到旧的Keychain API,因此我不得不深入研究的存档版本
创建访问对象
为了描述访问配置,我们必须使用所谓的访问对象(SecAccess
),它们具有关联的访问控制列表(SecACL
)。要了解有关ACL的更多信息,请参阅或文档版本中的说明。为了回答这个问题,ACL定义了哪个应用程序可以访问给定操作的Keychain项
使用SecAccessCreate(…)
可以使用预定义的系统默认配置创建新的访问对象,该配置基于提供的参数。默认情况下,它持有三个ACL。我试图按照@mike-c的回答中的建议添加一个新的ACL,但遇到了一个奇怪的行为,即对该项的访问有时被授予,有时不被授予
实现这一技巧的方法在的“高级主题”部分进行了描述。基本上,我们不添加新的ACL,而是修改现有的ACL之一
此函数为所有应用程序创建一个配置为无限制访问的访问对象。它是通过保持Keychain C API的样式用Swift编写的。这很难实现,但这一次获得了一致性
///使用系统默认配置创建一个access对象,该对象具有更改的ACL
///允许对所有应用程序进行访问。
///
///-参数描述符:应在安全对话框中显示的项目名称。
///-参数accessRef:指向新访问对象的指针。
///-返回:结果代码。
func SecAccessCreateForAllApplications(
描述符:CFString,
accessRef OuteracAccessRef:不可配置指针
)->骨状态{
var accessRef:SecAccess?
//创建一个不授予任何应用程序访问权限的访问对象(第二个参数)。
//它配置了3个默认ACL。
让accessCreateStatus=SecAccessCreate(
描述符,
[]作为CFArray,//没有应用程序具有访问权限
&accessRef
)
guard accessCreateStatus==errSecSuccess else{return accessCreateStatus}
guard let access=accessRef else{return accessCreateStatus}
//提取默认ACL