Sierra 中的安全/协同设计:钥匙串忽略访问控制设置和 UI-提示权限

security / codesign in Sierra: Keychain ignores access control settings and UI-prompts for permission

从 macOS Sierra 开始,如果没有 usr/bin/codesign UI,我无法再将代码签名身份导入到带有 /usr/bin/security 的钥匙串中 - 使用此身份时提示访问。这会破坏构建服务器的打包脚本。似乎没有解决方法。这会影响自定义创建的钥匙串,也会影响 login.keychain.

重现步骤: 在终端中执行以下命令(需要签名身份才能导入):

security create-keychain -p test buildagent.keychain
security unlock-keychain -p test buildagent.keychain

security list-keychains -d user -s buildagent.keychain
security default-keychain -s buildagent.keychain

security import identity.p12 -k buildagent.keychain -P password -T /usr/bin/codesign

codesign -vfs '$IDENTITY' '${PRODUCT}' --keychain 'buildagent.keychain'

结果:macOS 显示 UI-提示请求访问之前导入的私钥的权限。

我尝试了很多变通方法,但似乎没有任何效果:

导入身份确实有效,在钥匙串访问应用程序中显示钥匙串的内容时,我可以看到证书和密钥。私钥的访问控制设置也已正确配置(具有所需的代码设计例外规则)。

如何避免来自 Sierra 的 UI 提示?

您需要使用的命令如下:

security set-key-partition-list -S apple-tool:,apple: -s -k keychainPass keychainName

请记住,此命令行工具的工作方式类似于列表钥匙串的修改方式。 如果您使用单个值执行 set-key-partition-list,它将覆盖证书中的所有 partitionID。它不会验证传递的值。

此命令的作用是为可以为特定钥匙串签名 (-s) 的密钥设置 PartitionID(-S 之后的项目,以逗号分隔)。 允许代码签名的实际 partitionID 是 apple:.

我不知道 apple-tool: 在做什么,因为它没有记录在案,但在使用 security import 导入密钥后它就在那里,所以我保留它以避免破坏那些复制粘贴命令。

此更改是在 Mac OS Sierra 中引入的,但没有记录(或者至少我找不到文档)。截至 10 月 16 日,安全手册页仍未列出此命令。

有关详细信息,您可以参考此错误报告 - http://www.openradar.me/28524119

对于使用 Travis 或其他 CI 遇到此问题的用户,您必须在应用程序 ID 列表中添加 codesign

security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k keychainPass keychainName

P.S: 我正在使用 keychainName.keychain(添加 .keychain

来自 的命令只为我解锁了钥匙串,但我仍然有 UI 提示询问当前应用程序是否可以使用该密钥。

我这样阻止了提示:

转到钥匙串访问中的钥匙串,双击那里的所有钥匙,然后在“访问控制”选项卡中,选中'Allow all applications to access this item'。

然后我能够将新的钥匙串文件上传到我的 Jenkins 构建服务器,并在其中由 Keychains and Provisioning Profiles Plugin 解锁。构建现在成功签名。

出于某种原因,security set-key-partition-list 对我不起作用。

我在钥匙串中导入证书时使用-A选项解决了这个问题:

security import ${P12_FILE} -k ${KEYCHAIN_PATH} -P ${P12_PASSWORD} -A

以后就不用security set-key-partition-list了。

此选项允许任何应用程序在没有警告的情况下访问导入的密钥。因此,它可以防止提示出现。请注意,它是不安全的,因为密钥不受保护,但根据您的构建上下文,它可能会有所帮助。

此外,必须将钥匙串添加到搜索列表中:

security list-keychains -s ${KEYCHAIN_PATH}

那么钥匙串应该被解锁了。否则将显示询问钥匙串密码的提示:

security unlock-keychain -p ${KEYCHAIN_PASSWORD} ${KEYCHAIN_PATH}

最终应该禁用自动锁定超时。这是为了防止构建时间很长并且钥匙串自行重新锁定:

security set-keychain-settings ${KEYCHAIN_PATH}

在尝试了许多不同的解决方案后,对我有用的只是更改我的钥匙串的密码。

  • Finder > 前往 > 实用程序
  • 打开钥匙串访问实用程序。
  • 不确定我是否需要执行此步骤:在钥匙串访问实用程序的左侧栏中,单击我的证书。查看钥匙串列以确认您的苹果开发者证书在哪个钥匙串中。在我的例子中,它在 "login" 钥匙串中。
  • 更改上一步中钥匙串的密码。您可能想尝试锁定它然后解锁它(如果已锁定)。您可以通过单击相关的钥匙串("login",在我的例子中)来更改密码,然后从钥匙串访问实用程序的编辑菜单中选择 "Change Password..."。
  • 下次我 运行 Xcode 中的存档步骤(在“产品”菜单中)最终提示我输入钥匙串密码,我输入了 "login" 钥匙串的密码.然后它起作用了。完成后,我看到一个存档屏幕,其中列出了我的应用程序。

我花了几天时间寻找解决方案。这没有帮助

security import ${P12_FILE} -k ${KEYCHAIN_PATH} -P ${P12_PASSWORD} -A

但是当我明确列出应用程序时 - 它有效(至少在 Catalina 上)!

security import ${P12_FILE} -k ${KEYCHAIN_PATH} -P ${P12_PASSWORD} -T /usr/bin/codesign -T /usr/bin/productsign

仅次于使用

security set-key-partition-list -S apple-tool:,apple: -s -k keychainPass keychainName

我还必须将我的钥匙串设置更改为 "no timeout"

使用
security set-keychain-settings keychainName

(文档位于 https://ss64.com/osx/security-keychain-settings.html

上面的

None 有效,但我怀疑它确实适用于空钥匙串。问题在于,如果私钥已经存在于钥匙串中,那么 pkcs12 导入语句的访问控制修饰符 -A-T 将不起作用。现有密钥的访问列表未被覆盖。

将新证书导入 CI 服务器的钥匙串时,我们使用以下脚本来确保导入成功并且代码签名在访问控制列表中:

#!/bin/zsh
KC_FILE=keychain-path
KC_PASSWORD=keychain-password
P12_STORE=pkcs12-path
P12_PASSWORD=pkcs12-password

security unlock-keychain -p $KC_PASSWORD $KC_FILE

CERT_SHA1=`openssl pkcs12 -in $P12_STORE -nodes -passin pass:"$P12_PASSWORD" 2> /dev/null |openssl x509 -noout -fingerprint | grep Fingerprint | sed '/Fingerprint/s/^.*=//;s/://g'`

security delete-identity -Z $CERT_SHA1 $KC_FILE

security import $P12_STORE -t cert -f pkcs12 -P "$P12_PASSWORD" -T /usr/bin/codesign -k $KC_FILE

security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k $KC_PASSWORD $KC_FILE