代码签名和模糊身份,匹配“Mac开发者”和“iPhone开发者”。

9
我正在进行一项库的发行测试。该流程需要在越狱的iOS设备上进行测试。为此,我使用一台旧版 iPad 1,其运行着iOS 5.1系统并已越狱,使用了 RedSn0wRedSn0w 不会修补Gatekeeper服务(代码签名),因此我需要使用我的开发者账号并对我正在测试的二进制文件进行签名(Absinthe 修补了 Gatekeeper,这就是你可以使用 ldid 生成假签名的原因)。
尝试签名后出现以下结果:
$ codesign -s "John Doe" cryptest.exe 
John Doe: ambiguous (matches "Mac Developer: John Doe (3VT8SJ9C5)" and "iPhone Developer:
John Doe (3VT8SJ9C5)" in /Users/jdoe/Library/Keychains/login.keychain)

我浏览了codesign(1),但是由于它们具有相同的KeyIDs,我不知道如何解决它。使用KeyID会产生相同的消息。

在对可执行文件进行签名时如何消除歧义?

3个回答

16

含义模糊的证书

当密钥链中存在相同标识的两个证书时会出现这种情况:

codesign工具要求只有一个证书。

注意: 你的问题中提到的ldid可能需要更多的澄清,以说明它与你的苹果代码签名证书相关,或者确切的关注点是什么。

由于一个证书已经过期但从未被移除,因此重复的证书有时会出现在密钥链中。苹果有一些解决此类问题的说明,尽管如果以下步骤不起作用,您可能需要走一些非常规的程序来解决它:

  1. 在密钥链访问中,确保你的"视图"菜单 > "显示已过期的证书"选项已打开
  2. 点击"证书"类别,然后依次点击密钥链侧边栏中列出的每一个密钥链。如果看到任何重复的证书,即使是过期的证书,请删除这些重复的证书。
  3. 在密钥链访问中,点击"密钥"类别。
  4. 浏览每个密钥链,查找并删除任何与受影响的证书具有相同公共名称的"孤立密钥"。 "孤立密钥"是指没有与当前存在于密钥链中的iPhone开发人员或iPhone分发证书绑定的披露三角形的密钥。
  5. 如果您找到并删除了任何额外的密钥或证书,请重新尝试构建。
  6. 如果通过删除所有活动或过期的重复证书或密钥(由相同的公共名称)后问题仍然存在,则可以尝试使用"How do I delete/revoke my certificates and start over fresh?"中的步骤删除所有现有签名证书和密钥,并用新的替换它们。
  7. 最后,如果创建新证书后错误仍然存在,请在密钥链访问中对受影响的证书进行控制-单击,选择"新身份首选项",然后单击'证书'字段。如果在此处列出了重复的证书,则这是密钥链访问中已知且不常见的问题。为了解决此问题,请尝试以下操作:

    密钥链访问 > 编辑 > 密钥链列表,取消登录密钥链的“共享”选项。

如果返回到密钥链列表时,您发现登录密钥链仍标记为共享,请备份以下文件并删除它们(如果存在):

    /Library/Preferences/com.apple.security-common.plist
    ~/Library/Preferences/com.apple.security.plist

然后重新尝试构建...

如果您无法通过上述步骤解决问题,则尝试搜索错误消息中列出的证书之一。找到有问题的证书后,删除过期的证书或与所需证书冲突的证书。


多个代码签名证书(非重复)

如果您拥有多个代码签名证书,则需要使用-s选项指定要使用的证书(如果从命令行进行代码签名):

codesign -s <certificate name> -vvvv foo.app

-s, --sign identity 使用指定的身份标识对给定路径下的代码进行签名。详见 codesign 手册中的“签名身份”部分。

可选项:

-v, --verify 请求验证代码签名。如果还有其他操作(如签名、显示等),则 -v 将被解释为 --verbose。

例如,在您的情况下:

codesign -s "iPhone Developer: John Doe" cryptest.app

"由于您使用的是伪造证书..." - 但这些证书是真实的,并由苹果公司颁发。 - jww
@jww:我原本以为你是使用“ldid”生成虚假证书,然后用它们对代码进行签名,但我猜想这不是情况;也许你的问题需要一些澄清。无论如何,请看看所概述的步骤是否有助于解决问题... - l'L'l
不,他们是真的;对于混淆感到抱歉。如果我使用Absinthe,那么我可以使用虚假的证书。无论如何,我发现我必须使用完整的字符串:codesign -s“iPhone Developer: John Doe”cryptest.exe。如果您想回答,我很高兴接受。我甚至多年前在Crypto ++维基的iOS(命令行)上记录了其他方式,我从来没有需要这样做。 - jww
我一直拥有多个代码签名证书,并且总是使用-s选项,所以我甚至没有真正考虑过这个问题。我已经根据您的评论更新了答案,以反映解决方案 :) - l'L'l

2
如果您有多个(冲突的)证书名称,可以创建一个新的钥匙串并将所需的证书导入其中。在“钥匙串访问”中,“钥匙串”列表是可排序列表。因此,请确保您的新钥匙串位于列表顶部。
然后,在您的代码签名命令行中添加--keychain <path to new keychain file>。路径通常为/Users/<username>/Library/Keychains/<keychain name>.keychain-db

哇,这很棒!我相信它会解决我的难题。 - Richard Lalancette

0
另一种(或至少是hack的方法)解决歧义的方式是创建一个“钥匙串身份首选项”。
codesign man页面(man 1 codesign):
     -s, --sign identity
             Sign the code at the path(s) given using this identity. See
             SIGNING IDENTITIES below.

[...]

SIGNING IDENTITIES

[...]

     The identity is first considered as the full name of a keychain identity
     preference.  If such a preference exists, it directly names the identity
     used.  Otherwise, the identity is located by searching all keychains for a
     certificate whose subject common name (only) contains the identity string
     given.

钥匙串访问 中,证书上下文菜单中有一个项叫做 新身份首选项...,在这个选项中可以给出与证书相关联的 URL 或电子邮件地址。这是为了允许客户端证书与网站或电子邮件账户一起使用,但任意字符串都可以,例如:codesign-dev-id-app。该字符串直接赋值给 --sign 选项。
codesign --verbose --sign codesign-dev-id-app --timestamp foo.dmg

这对我有用(在macOS 10.13上),而将证书和密钥放在不同的钥匙串中则没有用,即使显式指定--keychaincodesign仍然在所有钥匙串中查找)。该字符串应谨慎选择,以避免与其预期目的意外冲突。一个由开发者拥有的域名下的虚拟URL可能是一个不错的选择。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接