39

下面是我的构建脚本(不使用 xcodebuild 插件)。

  1. 构建步骤工作
  2. 我创建了一个带有所需证书和私钥的单独钥匙串,它们在钥匙串访问中可见
  3. 钥匙串命令在脚本中不会失败
  4. security list-keychains 将这些显示为有效的钥匙串

就像解锁命令并没有真正成功一样。当我尝试从命令行通过

codesign -f -s "iPhone Developer: mycert" -v sample.app/ --keychain /Users/Shared/Jenkins/Library/Keychains/JenkinsCI.keychain

我明白了

CSSM_SignData returned: 000186AD
sample.app/: unknown error -2070=fffffffffffff7ea

虽然我不确定我是否正确地从命令行模拟,因为你充其量可以

sudo -u jenkins bash

xcodebuild ONLY_ACTIVE_ARCH="NO" CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED="NO" -scheme "MySchemeName" CONFIGURATION_BUILD_DIR="`pwd`"
security list-keychains -s /Users/Shared/Jenkins/Library/Keychains/JenkinsCI.keychain
+ security default-keychain -d user -s /Users/Shared/Jenkins/Library/Keychains/JenkinsCI.keychain
+ security unlock-keychain -p jenkins /Users/Shared/Jenkins/Library/Keychains/JenkinsCI.keychain
+ security list-keychains
    "/Users/Shared/Jenkins/Library/Keychains/JenkinsCI.keychain"
    "/Library/Keychains/System.keychain"
+ security default-keychain
    "/Users/Shared/Jenkins/Library/Keychains/JenkinsCI.keychain"
+ codesign -f -s '$IDENTITY_GOES_HERE.' -v sample.app/
sample.app/: User interaction is not allowed.

任何帮助是极大的赞赏。

4

12 回答 12

77

我们不使用 Jenkins,但我之前在我们的构建自动化中看到过这一点。以下是我们解决它的方法:

1)创建您的构建钥匙串。这将包含用于代码签名的私钥/证书:

security create-keychain -p [keychain_password] MyKeychain.keychain

keychain_password 由您决定。稍后您将在构建过程中使用它来解锁钥匙串。

2) 为您的 CodeSign 身份导入私钥 (*.p12):

security import MyPrivateKey.p12 -t agg -k MyKeychain.keychain -P [p12_Password] -A

这里的关键是“-A”标志。这将允许在没有警告的情况下访问钥匙串。这就是您看到“不允许用户交互”错误的原因。如果您尝试通过 Xcode UI 构建此版本,则会提示您“允许访问”您的钥匙串。

3)但是,您要保存钥匙串(例如:将其签入源代码管理),请确保它可由您的构建用户写入和执行。

当您准备好构建时,在运行 xcodebuild 之前添加以下内容:

# Switch keychain
security list-keychains -s "/path/to/MyKeyhain.keychain"
security default-keychain -s "/path/to/MyKeychain.keychain"
security unlock-keychain -p "[keychain_password]" "/path/to/MyKeychain.keychain"

如果您在本地运行,您可能希望在构建脚本的末尾添加一些内容,以切换回登录钥匙串(~/Library/Keychains/login.keychain),例如:

# Switch back to login keychain
security list-keychains -s "~/Library/Keychains/login.keychain"
security default-keychain -s "~/Library/Keychains/login.keychain"

试试看。我们为我们使用的每个身份创建一个单独的钥匙串(我们自己的 plus 代表客户构建)。在我们公司的案例中,我们同时拥有 AppStore 和 Enterprise 帐户。这可能会导致在共同设计时出现命名冲突(例如:两个帐户都解析为“iPhone Distribution: ACME Corporation”)。通过将这些身份保存在单独的钥匙串中,我们避免了这种冲突。

于 2013-10-23T19:15:10.687 回答
27

将证书移动到系统钥匙串,并引用它专门解决了这个问题

于 2013-05-14T19:51:36.467 回答
18

在这个答案中,我们添加/删除您的 iOS 证书,无需操作登录钥匙串,也无需更改默认钥匙串:

  1. 使用临时钥匙串
  2. 将临时钥匙串附加到搜索列表(不替换)
  3. 无超时解锁临时钥匙串
  4. 使用导入您的证书-T /usr/bin/codesign
  5. 进行构建
  6. 通过删除临时钥匙串来删除证书

创建一个临时钥匙串。我添加$$了哪个 PID 来为钥匙串创建一个唯一的名称。这允许创建多个临时钥匙串而不会发生冲突。如果我们同时运行 Jenkins 作业,这很有用。

# Create temporary keychain
MY_KEYCHAIN="MyKeychain-$$.keychain"
MY_KEYCHAIN_PASSWORD="secret"
security create-keychain -p "$MY_KEYCHAIN_PASSWORD" "$MY_KEYCHAIN"

将临时钥匙串附加到搜索列表。小心使用security list-keychains -s附加您的钥匙串,否则,您将破坏在另一个线程中运行的构建:

# Append keychain to the search list
security list-keychains -d user -s "$MY_KEYCHAIN" $(security list-keychains -d user | sed s/\"//g)
security list-keychains

解锁临时钥匙串,没有自动重新锁定超时 ( security set-keychain-settings)。如果您忘记修复重新锁定超时,构建时间超过默认重新锁定超时(通常大约 30 分钟)将触发密码提示:

# Unlock the keychain
security set-keychain-settings "$MY_KEYCHAIN"
security unlock-keychain -p "$MY_KEYCHAIN_PASSWORD" "$MY_KEYCHAIN"

导入 iOS 证书并授予/usr/bin/codesign访问权限,无需密码提示。

# Import certificate
security import $CERT -k "$MY_KEYCHAIN" -P "$CERT_PASSWORD" -T "/usr/bin/codesign"

由于临时钥匙串仅包含 1 个证书,我们可以通过编程方式派生 IOS_IDENTITY(通常需要作为构建步骤的输入)。

# Detect the iOS identity
IOS_IDENTITY=$(security find-identity -v -p codesigning "$MY_KEYCHAIN" | head -1 | grep '"' | sed -e 's/[^"]*"//' -e 's/".*//')
IOS_UUID=$(security find-identity -v -p codesigning "$MY_KEYCHAIN" | head -1 | grep '"' | awk '{print $2}')

security set-key-partition-list是解锁证书的新/附加要求。

# New requirement for MacOS 10.12
security set-key-partition-list -S apple-tool:,apple: -s -k $MY_KEYCHAIN_PASSWORD $MY_KEYCHAIN

现在做你的构建:

# Insert your custom build steps

删除临时钥匙串。因为构建完成,我们不再需要钥匙串和证书。删除临时钥匙串会自动将其从搜索列表中弹出。即所有其他钥匙串都将保留。

# Delete the temp keychain
security list-keychains
security delete-keychain "$MY_KEYCHAIN"
security list-keychains
于 2016-03-14T00:18:03.057 回答
16

在签署“security unlock-keychain -p”之前需要解锁钥匙串

于 2013-06-18T20:18:25.433 回答
9

只有一件事为我解决了这个问题。

我所做的是在钥匙串访问中设置签名证书的私钥以允许所有应用程序访问此项目

在此处输入图像描述

于 2018-10-03T14:52:31.293 回答
5

FWIW ...让我抛出另一个可能的原因。您可能有重复的证书在四处飘荡,codesign不知道该使用哪一个。当您从 Jenkins 从站运行此命令时,您是否看到重复的有效证书?像这样的东西:

$ security find-identity -v -p codesigning
  1) AAAAE00066DED2FE77DF43012573AD5B6188AAAA "iPhone Developer: JOHN SMITH (XAAAAFSUSJ)"
  2) AAAAE00066DED2FE77DF43012573AD5B6188AAAA "iPhone Developer: JOHN SMITH (XAAAAFSUSJ)"
  3) BBBB5B03DB566209964247982908D3DD74D1BBBB "iPhone Distribution: Example, Inc. (TBBBBH5HUE)"
  4) BBBB5B03DB566209964247982908D3DD74D1BBBB "iPhone Distribution: Example, Inc. (TBBBBH5HUE)"
  5) BBBB5B03DB566209964247982908D3DD74D1BBBB "iPhone Distribution: Example, Inc. (TBBBBH5HUE)"
  6) AAAAE00066DED2FE77DF43012573AD5B6188AAAA "iPhone Developer: JOHN SMITH (XAAAAFSUSJ)"
  7) AAAAE00066DED2FE77DF43012573AD5B6188AAAA "iPhone Developer: JOHN SMITH (XAAAAFSUSJ)"
  8) BBBB5B03DB566209964247982908D3DD74D1BBBB "iPhone Distribution: Example, Inc. (TBBBBH5HUE)"
  8 valid identities found

如果是这样,我发现执行以下操作并返回到签名证书的基线集很有用:

  • 删除 Jenkins 从站(以及将运行您的构建脚本的其他 Jenkins 从站)上的所有证书。
  • 下一步:验证,你已经再次0 identifies运行$ security find-identity -v -p codesigning
  • 在应用程序的存储库中包含一个自定义MyApp.keychain,其中包含两个有效证书。请务必删除所有重复项。
  • 现在,从您的构建脚本中,在codesign进程从解锁 MyApp.keychain运行之前将其设置为默认值。这会将这些证书公开为可用于codesign.
  • 最后,再次验证您的 Jenkins 从站:$ security find-identity -v -p codesigning看到捆绑到的证书,MyApp.keychain并且系统上没有其他签名身份。如果您在完成此操作后仍然看到重复项,那么您的 Jenkins 奴隶在其他地方也知道这些证书。
于 2017-08-22T16:35:06.297 回答
3

我将所有证书/私钥复制到一个新的钥匙串(您可以右键单击这些项目并简单地复制和粘贴)。在新的钥匙串中,右键单击每个私钥,获取信息 -> 访问控制,然后将密钥提供给所有应用程序。

重要的是,钥匙串应用程序的左上角是钥匙串列表。重新排序它们,使新的钥匙串在列表中排在第一位。

我发现的另一个答案给出了在构建过程中解锁此钥匙串的构建步骤:

KEYCHAIN=/Users/<you>/Library/Keychains/codesign.keychain

# the -s option adds $KEYCHAIN to the search scope, while the -d option adds $KEYCHAIN to the system domain; both are needed
security -v list-keychains -d system -s $KEYCHAIN
security -v unlock-keychain -p <keychain password> $KEYCHAIN
于 2013-07-25T15:16:19.130 回答
2

这对我有用:

  1. 我创建了一个新的钥匙串并将所有条目从“登录”复制到它,命名为“jenkins_ios”
  2. 将新的钥匙串设为默认值。
  3. 在 Jenkins 配置中添加了一个新的“执行 shell”步骤,它应该是代码签名之前的第一步,包含以下内容:

KEYCHAIN=/Users/<user>/Library/Keychains/jenkins_ios.keychain
security -v list-keychains -s $KEYCHAIN
security -v unlock-keychain -p <password> $KEYCHAIN
security set-keychain-settings -t 3600 -l $KEYCHAIN

最后一步非常重要,因为默认的解锁超时时间可能不足以让您的项目正确构建(这正是我们的项目所发生的,因为它很大,构建步骤大约需要 5-7 分钟,并且此时钥匙串已被锁定它是协同设计所必需的)。

于 2015-12-16T09:20:45.143 回答
1

这也可能是由钥匙串上的默认超时引起的。

查看我对“不允许用户交互”的回答,尝试使用 codesign 对 OSX 应用程序进行签名

于 2014-06-03T11:29:26.870 回答
1

这是一个代码签名错误,xcodebuild 命令无法访问您证书的私钥,因为它是通过 Jenkins 的 SSH 从站运行的。

在运行 xcodebuild 之前,在 shell 脚本中运行此行以允许访问:

security set-key-partition-list -S apple-tool:,apple: -s -k <ROOT-PASSWORD> /Users/<YOUR USER NAME>/Library/Keychains/login.keychain-db

希望有帮助!

于 2017-07-28T22:36:29.660 回答
1

如果你在 CI 上遇到这个问题(在我的例子中是 GitHub Actions)。然后不要忘记在运行xcodebuild命令之前解锁安装证书的钥匙串。

例如: security -v unlock-keychain -p <keychain password> $KEYCHAIN

如果钥匙串被锁定,该xcodebuild命令将在尝试签署应用程序时挂起/冻结,因为它将等待输入钥匙串密码,因此这是一个 CI,而不是您自己的机器,当您无法输入密码时被要求。

如果您在没有代码签名的情况下构建应用程序,则不需要解锁钥匙串,例如... CODE_SIGNING_ALLOWED=NO CODE_SIGNING_REQUIRED=NO CODE_SIGN_IDENTITY="" ...

于 2021-02-24T18:01:35.980 回答
0

我从钥匙链(登录和系统)中删除了重复的钥匙,它开始工作了。我确实只有一个证书,但有很多密钥,所以我必须过滤密钥才能正确查看它们。

于 2017-12-01T12:01:56.483 回答