如何使用 SignTool 对应用包进行签名

注意

有关对 Windows 应用包进行签名,请参阅使用 SignTool 对应用包进行签名

了解如何使用 SignTool 对应用包进行签名,以便进行部署。 SignTool 是 Windows 软件开发工具包 (SDK) 的一部分。

必须对所有 Windows 应用包进行数字签名,然后才能进行部署。 虽然 Microsoft Visual Studio 2012 及更高版本可以在创建应用包期间对应用包进行签名,但使用 Windows SDK 中的应用包生成工具 (MakeAppx.exe) 工具创建的包不会进行签名。

注意

只能使用 SignTool 在 Windows 8 及更高版本或 Windows Server 2012 及更高版本上对 Windows 应用包进行签名。 不能在 Windows 7 或 Windows Server 2008 R2 等下层操作系统上使用 SignTool 对应用包进行签名。

需要了解的事项

技术

先决条件

其他注意事项

用于对应用包进行签名的证书必须满足以下条件:

  • 证书的使用者名称必须与存储在包中的 AppxManifest.xml 文件的 Identity 元素中包含的 Publisher 属性相匹配。 发布者名称是打包的 Windows 应用的标识的一部分,因此必须使证书的使用者名称与应用的发布者名称匹配。 这允许根据数字签名检查已签名包的身份。 有关使用 SignTool 对应用包进行签名时可能出现的签名错误的信息,请参阅如何创建应用包签名证书的“备注”部分。

  • 证书必须对代码签名有效。 这意味着这两个项都必须为 true:

    • 证书的扩展密钥用法 (EKU) 字段必须未设置或包含代码签名的 EKU 值 (1.3.6.1.5.5.7.3.3)。
    • 证书的密钥用法 (KU) 字段必须未设置或包含数字签名 (0x80) 的用法位。
  • 证书包含私钥。

  • 证书有效。 它处于活动状态,尚未过期,也未被吊销。

说明

第 1 步:确定要使用的哈希算法

在对应用包进行签名时,必须使用与创建应用包时相同的哈希算法。 如果使用默认设置创建应用包,则使用的哈希算法为 SHA256。

如果使用具有特定哈希算法的应用包生成工具来创建应用包,请使用相同的算法对包进行签名。 若要确定用于对包进行签名的哈希算法,可以提取包内容并检查 AppxBlockMap.xml 文件。 BlockMap 元素的 HashMethod 属性指示创建应用包时使用的哈希算法。 例如:

<BlockMap xmlns="http://schemas.microsoft.com/appx/2010/blockmap" 
HashMethod="https://www.w3.org/2001/04/xmlenc#sha256">

前面的 BlockMap 元素指示使用了 SHA256 算法。 此表列出了当前可用算法的映射:

HashMethod 要使用的 hashAlgorithm
https://www.w3.org/2001/04/xmlenc#sha256 SHA256(.appx 默认值)
https://www.w3.org/2001/04/xmldsig-more#sha384 SHA384
https://www.w3.org/2001/04/xmlenc#sha512 SHA512

第 2 步:运行 SignTool.exe 对包进行签名

使用 .pfx 文件中的签名证书对包进行签名

  • SignTool sign /fd hashAlgorithm /a /f signingCert.pfx /p password filepath.appx
    

如果未指定 /fd hashAlgorithm 参数,则 SignTool 将 /fd hashAlgorithm 参数默认为 SHA1,并且 SHA1 对应用包进行签名无效。 因此,在对应用包进行签名时必须指定此参数。 若要对使用默认 SHA256 哈希创建的应用包进行签名,请将 /fd hashAlgorithm 参数指定为 SHA256:

SignTool sign /fd SHA256 /a /f signingCert.pfx /p password filepath.appx

如果使用不受密码保护的 .pfx 文件,则可以省略 /p password 参数。 还可以使用 SignTool 支持的其他证书选择选项对应用包进行签名。 有关这些选项的详细信息,请参阅 SignTool

注意

不能对已签名的应用包使用 SignTool 时间戳操作;不支持该操作。

如果要对应用包进行时间戳,则必须在签名操作期间执行此操作。 例如:

SignTool sign /fd hashAlgorithm /a /f signingCert.pfx /p password /tr timestampServerUrl 
filepath.appx

使 /tr timestampServerUrl 参数等于 RFC 3161 时间戳服务器的 URL。

注解

本部分讨论如何排查应用包的签名错误。

排除应用包签名错误

除了 SignTool 可以返回的签名错误之外,SignTool 还可以返回特定于应用包签名的错误。 这些错误通常显示为内部错误:

SignTool Error: An unexpected internal error has occurred.
Error information: "Error: SignerSign() failed." (-2147024885 / 0x8007000B) 

如果错误代码以 0x8008 开头,例如,0x80080206 APPX_E_CORRUPT_CONTENT),则表示正在签名的包无效。 在这种情况下,必须先重新生成包,然后才能对包进行签名。 有关 0x8008* 错误的完整列表,请参阅 COM 错误代码(安全和设置)

更常见的错误是 0x8007000b (ERROR_BAD_FORMAT)。 在这种情况下,可以在事件日志中找到更具体的错误信息:

搜索事件日志

  1. 运行 Eventvwr.msc。
  2. 打开事件日志:事件查看器(本地)-> 应用程序和服务日志 -> Microsoft -> Windows -> AppxPackagingOM -> Microsoft-Windows-AppxPackaging/Operational
  3. 查找最近的错误事件。

内部错误通常对应于以下其中一个:

事件 ID 示例事件字符串 建议
150 错误 0x8007000B:应用部件清单 (manifest) 发布者名称 (CN=Contoso) 必须与签名证书的使用者名称 (CN=Contoso, C=US) 匹配。 应用部件清单 (manifest) 发布者名称必须与签名的使用者名称完全匹配。 注意:这些名称用引号指定,区分大小写和空格。
可以更新 AppxManifest.xml 文件中为 Identity 元素定义的 Publisher 属性字符串,以匹配预期签名证书的使用者名称。 或者,选择具有与应用清单发布者名称匹配的使用者名称的其他签名证书。 清单发布者名称和证书使用者名称都列在事件消息中。
151 错误 0x8007000B:指定的签名哈希方法 (SHA512) 必须与应用包块映射中使用的哈希方法 (SHA256) 匹配。 /fd 参数中指定的 hashAlgorithm 不正确(请参阅第 1 步:确定要使用的哈希算法)。 使用与应用包块映射匹配的 hashAlgorithm 重新运行 SignTool
152 错误 0x8007000B:应用包内容必须根据其块映射进行验证。 应用包已损坏,需要重新生成以生成新的块映射。 有关创建应用包的详细信息,请参阅使用应用包生成工具创建应用包或使用 Visual Studio 2012 创建应用包

安全注意事项

在对包进行签名后,用于对包进行签名的证书必须仍然受到部署包的计算机的信任。 通过将证书添加到本地计算机证书存储,你会影响计算机上的所有用户的证书信任。 我们建议将测试应用包所需的任何代码签名证书安装到受信任的人员证书存储中,并在不再需要时立即删除这些证书。 如果创建自己的测试证书来对应用包进行签名,我们还建议限制与测试证书相关联的权限。 有关创建用于签名应用包的测试证书的详细信息,请参阅如何创建应用包签名证书

示例

创建应用包示例

概念

代码签名最佳做法

在 Visual Studio 2012 中对包进行签名

SignTool

应用包生成工具 (MakeAppx.exe)

如何创建应用包签名证书