目录
注:本文主要译自MSDN官方文档,如有不恰当指出欢迎评论区提出。英语OK的建议参考官方链接:Sign an app package using SignTool ,Create a certificate for package signing,Package a UWP app with Visual Studio
创建数字签名
创建自签名证书
确定待打包应用的颁发者(Subject)
要想使用数字证书对APP签名,那么证书的颁发者必须与应用清单文件(manifest)中的Publisher
相同,例如对于下面的应用程序清单代码块,对应的签名颁发者必须与其中的Publisher
选项值一样,即CN=Contoso Software, O=Contoso Corporation, C=US
。
<Identity Name="Contoso.AssetTracker"
Version="1.0.0.0"
Publisher="CN=Contoso Software, O=Contoso Corporation, C=US"/>
使用 New-SelfSignedCertificate 命令创建证书
在Powershell(管理员)中可以使用 New-SelfSignedCertificate
命令创建自签名的证书。该命令有多个可以自定义参数,本文主要关注其中与SignTool配合使用的几个参数。更多信息,参阅New-SelfSignedCertificate.
以前述的应用程序清单代码块为例,应使用如下命令创建证书:
New-SelfSignedCertificate -Type Custom -Subject "CN=Contoso Software, O=Contoso Corporation, C=US" -KeyUsage DigitalSignature -FriendlyName "Your friendly name goes here" -CertStoreLocation "Cert:\LocalMachine\My" -TextExtension @("2.5.29.37={text}1.3.6.1.5.5.7.3.3", "2.5.29.19={text}")
其中:
- KeyUsage:该参数指示证书的使用方式。对于自签名证书,该参数值应当为
DigitalSignature
- TextExtension:该参数包含了如下扩展的设置
- Extended Key Usage (EKU):该扩展指示了证书公钥(public key)的额外使用目的,对于自签名证书来说,该参数应当包含字符串
2.5.29.37={text}1.3.6.1.5.5.7.3.3
,该字符串表示该证书用于代码签名(code signing)。 - Basic Constraints:该扩展表明了该证书是否是一个 Certificate Authority (CA),对于自签名证书,该扩展选项应当包含字符串
2.5.29.19={text}
,表示该证书是end entity(not a CA)
。
上述命令执行过后,证书会被添加到计算机的证书商店中(CertStoreLocation
选项 ),改名了也会自动产生的指纹。下列指令可以查看安装的证书,当然你也可以在管理计算机证书控制台的证书本地计算机-个人-证书中查看安装的证书。
- Extended Key Usage (EKU):该扩展指示了证书公钥(public key)的额外使用目的,对于自签名证书来说,该参数应当包含字符串
Set-Location Cert:\LocalMachine\My
Get-ChildItem | Format-Table Subject, FriendlyName, Thumbprint
导出证书
导出安装的证书(pfx文件)需要使用Powershell中的**Export-PfxCertificate **命令,使用该命令时,你必须创建一个密码-Password
选项,或者使用-ProtectTo
选项致命无需密码即可访问的用户或组。两者都未指明时会产生错误。
使用-Password:
$pwd = ConvertTo-SecureString -String <Your Password> -Force -AsPlainText
Export-PfxCertificate -cert "Cert:\LocalMachine\My\<Certificate Thumbprint>" -FilePath <FilePath>.pfx -Password $pwd
使用-ProtectTo:
Export-PfxCertificate -cert Cert:\LocalMachine\My\<Certificate Thumbprint> -FilePath <FilePath>.pfx -ProtectTo <Username or group name>
创建完成后就可以使用SignTool来对应用程序进行签名了。
注:将证书添加到计算机中会影响该计算机的所有用户。建议当不在需要该证书时将其移除。
打包应用程序
创建过数字签名之后即可对项目进行打包。首先我们需要在Package.appxmanifest文件中设置程序包的签名信息。选择以查看代码方式打开Package.appxmanifest文件,更改如下代码块中的Publisher
选项,该选项对应于上述签名过程中填写的信息。
<Identity
Name="WindowsTerminalDev"
Publisher="CN=你的信息, O=你的信息, C=US"
Version="0.0.3.0" />
之后 在右键应用包,在弹出菜单的应用商店项中就可以对APP进行打包了,具体打包过程较为简单,不再赘述。
使用SignTool进行签名
在使用该命令前请确保你已经拥有一个打包好的app、有效的签名证书以及SignTool.exe,其中SignTool可以在SDK中找到:
- x86: C:\Program Files (x86)\Windows Kits\10\bin\x86\SignTool.exe
- x64: C:\Program Files (x86)\Windows Kits\10\bin\x64\SignTool.exe
(我的电脑上在C:\Program Files (x86)\Windows Kits\10\bin\10.0.18362.0\x64
文件夹中)
使用SignTool
SignTool可以对文件签名、验证签名或时间戳、移除签名等。下文主要关注签名的过程,更多信息参阅SignTool。
确定哈希算法
使用SignTool时需要确定APP打包时的哈希算法,可以通过提取已经打包的APP文件AppxBlockMap.xml
查看。具体提取方法查看:提取打包文件。一般情况下APP打包时使用的哈希算法是SHA256。
注:SignTool的默认算法是SHA1,而该算法 MakeAppx.exe 是不支持的,因此使用时必须确定算法。
对APP进行签名
注:由于SignTool无法被Powershell识别,因此需要进入SignTool.exe的文件夹中并按./SignTool.exe …**方式执行下述的所有命令。
通用的签名语法为:
SignTool sign [options] <filename(s)>
使用.pfx
文件对APP签名,使用如下命令语法:
SignTool sign /fd <Hash Algorithm> /a /f <Path to Certificate>.pfx /p <Your Password> <File path>.appx
或者:
SignTool sign /fd <Hash Algorithm> /a /f <Path to Certificate>.pfx /p <Your Password> <File path>.msix
若不适用文件而是使用证书商店的证书,则使用如下命令:
SignTool sign /fd <Hash Algorithm> /sha1 <SHA1 hash> <File Path>.appx
SignTool sign /fd <Hash Algorithm> /sha1 <SHA1 hash> <File Path>.msix
注意,有些证书不需要密码,使用这些证书时去掉 /p <Your Password>
即可。
常见错误及解决
使用SignTool最常见的错误是:
SignTool Error: An unexpected internal error has occurred.
Error information: "Error: SignerSign() failed." (-2147024885 / 0x8007000B)
如果错误代码已0x8008开头,那么表明签名的APP包是无效的,需要重新打包并再次签名。SignTool工具同时也提供了调试信息,在sign
参数后添加/debug
选项即可生成调试信息。
另一种常见的错误是0x80070000B
,对于这种错误(建议先看看下面的错误原因),可以使用事件查看器->应用和服务日志->Microsoft->Windows->AppxPackagingOM-> Microsoft-Windows-AppxPackaging/Operational
,然后在最近的错误事件中查看。如下为对应的错误原因:
Event ID | Example event string | Suggestion |
---|---|---|
150 | error 0x8007000B:The app manifest publisher name (CN=Contoso) must match the subject name of the signing certificate (CN=Contoso,C=US). | The app manifest publisher name must exactly match the subject name of the signing. |
151 | error 0x8007000B: The signature hash method specified (SHA512) must match the hash method used in the app package block map (SHA256). | The hashAlgorithm specified in the /fd parameter is incorrect. Rerun SignTool using hashAlgorithm that matches the app package block map (used to create the app package) |
152 | error 0x8007000B:The app package contents must validate against its block map. | The app package is corrupt and needs to be rebuilt to generate a new block map. For more about creating an app package, see Create an app package with the MakeAppx.exe tool |