使用安全性为/usr/bin/codesign创建钥匙串
导入证书并使其与codesign程序化地工作并不是使用登录或系统钥匙串或向某个codesign之神祈求的问题。您只需要设置正确的权限即可。我建议专门为codesign目的创建一个新的钥匙串。
现在,要想使codesign
不产生errSecInternalComponent
错误,您需要获取分区列表(ACL)的正确设置。我将逐步介绍如何实现:
创建钥匙串
security create-keychain -p "${KEYCHAIN_PASSWORD}" "${KEYCHAIN_NAME}"
此时钥匙串已经解锁,但是不会出现在 钥匙串访问
中。
将新的钥匙串添加到搜索列表中
security list-keychains -s "${KEYCHAIN_NAME}" "${OLD_KEYCHAIN_NAMES[@]}"
将新的Keychain添加到列表中。如果你不首先从list-keychains
中获取原始列表,那么在搜索列表中就不再有login.keychain
了。
解锁钥匙串
security unlock-keychain -p "${KEYCHAIN_PASSWORD}" "${KEYCHAIN_NAME}"
如果您已经创建了Keychain,则此操作是多余的。但是,如果Keychain已经存在,则有必要进行此操作。
从Keychain中删除默认值
security set-keychain-settings "${TESTING_KEYCHAIN}"
如果不指定任何参数,这将把自动锁定超时设置为无限并在睡眠时取消自动锁定。
从.p12文件导入您的签名证书
security import "${DIST_CER}" -P "${CERTIFICATE_PASSWORD}" -k "${KEYCHAIN_NAME}" -T /usr/bin/codesign
导入证书并通过-T
选项授予codesign
访问权限。
设置钥匙串上的ACL
security set-key-partition-list -S apple-tool:,apple: -s -k "${KEYCHAIN_PASSWORD}" "${KEYCHAIN_NAME}"
许多人都会忽略这个要求。你可以使用dump-keychain查看macOS的操作方式。在签名代码时,需要使用apple:
和apple-tool:
。 -s
表示签名证书。
我的签名证书在哪里?
确保自己能够找到证书是个好主意。
security find-identity -p codesigning -v /path/to/keychain
Gitlab-Runner、Jenkins等
对于任何CI类型的runner或构建系统而言,确保从launchd
正确启动进程非常重要。请确保您的plist文件包含<SessionCreate></true>
。
如果没有将钥匙串的所有者与构建过程正确匹配,并确保创建了安全会话,将导致各种问题。从诊断的角度来看,您可以引入list-keychains
并查看输出是否符合您的期望。
这是来自launchd.plist
手册页的内容:
SessionCreate <boolean>
此键指定作业应生成到新的安全审计会话中,而不是默认会话,因为它属于该上下文的。有关详细信息,请参见auditon(2)。
UserName <string>
此可选键指定要运行作业的用户。此键仅适用于加载到特权系统域中的服务。
GroupName <string>
此可选键指定要运行作业的组。此键仅适用于加载到特权系统域中的服务。如果设置了UserName而未设置GroupName,则该组将设置为用户的主要组。
示例 /Library/LaunchDaemons/com.company.gitlab-runner.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.company.gitlab-runner</string>
<key>SessionCreate</key><true/>
<key>KeepAlive</key><true/>
<key>Disabled</key><false/>
<key>UserName</key>
<string>bob</string>
<key>GroupName</key>
<string>staff</string>
<key>ProgramArguments</key>
<array>
<string>/usr/local/opt/gitlab-runner/bin/gitlab-runner</string>
<string>run</string>
<string>--working-directory</string>
<string>/Users/bob/gitlab-runner</string>
<string>--config</string>
<string>/Users/bob/gitlab-runner/config.toml</string>
<string>--service</string>
<string>gitlab-runner</string>
<string>--syslog</string>
</array>
<key>EnvironmentVariables</key>
<dict>
<key>PATH</key>
<string>/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin</string>
</dict>
</dict>
</plist>
注册Runner
gitlab-runner register \
--non-interactive \
--tls-ca-file "{{ gitlab_runner_dir }}/certs/git.company.com.crt" \
--config "{{ gitlab_runner_dir }}/config.toml" \
--builds-dir "{{ gitlab_runner_dir }}/builds" \
--url "{{ gitlab_ci }}" \
--registration-token "{{ gitlab_token }}" \
--name "{{ computername }}" \
--tag-list "{{ gitlab_runner_tags }}" \
--output-limit 16384 \
--executor shell \
--shell bash
最终的代码签名
您可以使用find-identity
查找签名证书的哈希值。
security find-identity -p codesigning -v
在开始签署Xcode之前,需要设置环境变量CODESIGN_ALLOCATE
以使用Xcode附带的codesign_allocate
而不是/usr/bin
中的。
export CODESIGN_ALLOCATE="$( xcrun --find codesign_allocate )"
代码签名框架、dylib等
如果您是手动进行代码签名,请从frameworks
和dylibs
开始,并在它们全部签名后再签署.app
。换句话说,您需要从下往上进行代码签名。
/usr/bin/codesign --verbose=4 -f -s "$SIGNER_HASH" "$SIGNABLE"
对应用程序包进行代码签名
在所有其他可签名内容都已签名后,对 .app 文件本身进行签名。理论上,您可以使用 --deep
一次性完成所有操作,但是,您仍需要确保您的应用程序具有授权和可能需要其他标志。
/usr/bin/codesign --verbose=4 -f -s "$SIGNER_HASH" "$SIGNABLE"
应用到所有项目的标志:
应用签名步骤中的其他标志:
--entitlements /path/to/entitlements.xcent
新的权限
--preserve-metadata=entitlements
保留当前权限
新的代码签名要求 - DER编码的权限
苹果最近开始要求权限不仅以plist形式嵌入,还要以DER编码形式嵌入。如果您使用的是较旧的Mac/Xcode,则可能会遇到错误...
代码签名版本不再受支持