我正在尝试使用我的 EV 代码签名证书对我的 MAUI Blazor (Windows) 应用程序进行代码签名。我已经在 YubiKey 5 FIPS 设备上安装了我的证书。当我运行以下命令时,应用程序开始构建。然后当需要签署包裹时,我被要求提供我的密码(用于 YubiKey)。输入密码后,我得到以下异常。
命令:
"C:\Program Files\Microsoft Visual Studio\2022\Preview\MSBuild\Current\Bin\msbuild" /restore /t:Publish /p:TargetFramework=net6.0-windows10.0.19041 /p:configuration=release /p:GenerateAppxPackageOnBuild=true /p:AppxPackageSigningEnabled=true /p:PackageCertificateThumbprint="KeyThumbprint" /p:PackageCertificatePassword="password"
例外:
C:\Users\user\.nuget\packages\microsoft.windowsappsdk\1.0.0\build\Microsoft.Build.Msix.Packaging.targets(462,5): error
APPX1204: Failed to sign 'path/to/my.msix'
. SignTool Error: An unexpected internal error has occurred. [path/to/my/project.csproj]
C:\Users\user\.nuget\packages\microsoft.windowsappsdk\1.0.0\build\Microsoft.Build.Msix.Packaging.targets(462,5): error
APPX1204: [path/to/my/project.csproj]
此外,如果我尝试代码唱歌工具,我会收到以下错误:
"Error: SignerSign() failed." (-2146435068/0x80100004)
代码签名.exe 命令
signtool.exe sign /fd sha256 /a /sha1 my_thumbprint "path/to/my.msix"
过去我有一个自签名的代码签名证书可以工作。这表明上述命令是正确的。
视觉工作室
您可以更新 MAUI .csproj 文件以包含以下内容。这将允许以开发者模式或使用 EV 证书登录。我没有具体使用过 YubiKey,但应该是一样的。请务必将 A1B2C3... 替换为您的开发者证书指纹,并将 D4E5F6... 替换为您的 EV 代码证书指纹。
<PropertyGroup>
<AppxPackageSigningEnabled>True</AppxPackageSigningEnabled>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)' == 'Debug'">
<PackageCertificateThumbprint>A1B2C3...</PackageCertificateThumbprint>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)' == 'Release'">
<PackageCertificateThumbprint>D4E5F6...</PackageCertificateThumbprint>
</PropertyGroup>
<PropertyGroup Condition="$(TargetFramework.Contains('-windows')) and '$(Configuration)' == 'Release'">
<GenerateAppxPackageOnBuild>true</GenerateAppxPackageOnBuild>
</PropertyGroup>
PowerShell
或者您可以使用此 PowerShell 脚本来完全自动化发布过程,并避免弹出用于密码的 EV 代码证书对话框。这是我的首选方法。
这里有几个替换项可以根据您的项目进行定制;如果您使用的是纯文本密码文件,请确保将它们保存在某种形式的安全存储中,例如 BitLocker VHD。
一些注意事项:
C:\MyProject
、C:\Logs
或D:\EncryptedStorage
1.0.0.0
替换为当前版本# Update manifest file
$certificate = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2 "D:\EncryptedStorage\MyCertificate.cer"
$file = "C:\MyProject\Platforms\Windows\Package.appxmanifest"
$xml = [Xml] (Get-Content $file)
$xml.Package.Identity.Publisher = $certificate.Subject
$xml.Package.Properties.PublisherDisplayName = $certificate.Subject -replace "(CN=)(.*?),.*", '$2'
$xml.Save($file)
# Publish
$dotnet = "C:\Program Files\dotnet\dotnet.exe"
$arguments = New-Object System.Collections.Generic.List[System.String]
$arguments.Add("publish")
$arguments.Add("C:\MyProject\MyProject.csproj")
$arguments.Add("-c Release")
$arguments.Add("-f net6.0-windows10.0.19041.0")
$publish = Start-Process -NoNewWindow -FilePath $dotnet -PassThru -ArgumentList $arguments.ToArray() -RedirectStandardOutput "C:\Logs\PublishLog.txt"
Wait-Process -InputObject $publish
# Sign
$container = Get-Content "D:\EncryptedStorage\MyCertificateContainer.txt"
$pw = Get-Content "D:\EncryptedStorage\MyCertificatePassword.txt"
$arguments = New-Object System.Collections.Generic.List[System.String]
$arguments.Add("sign")
$arguments.Add("/tr http://timestamp.sectigo.com")
$arguments.Add("/td SHA256")
$arguments.Add("/f D:\EncryptedStorage\MyCertificate.cer")
$arguments.Add("/fd SHA256")
$arguments.Add("/csp ""eToken Base Cryptographic Provider""")
$arguments.Add("/kc ""[{{${pw}}}]=${container}""")
$arguments.Add("C:\MyProject\bin\Release\net6.0-windows10.0.19041.0\win10-x64\AppPackages\MyProject_1.0.0.0_Test\MyProject_1.0.0.0_x64.msix"))
Copy-Item "D:\EncryptedStorage\MyCertificate.cer" -Destination "C:\MyProject\bin\Release\net6.0-windows10.0.19041.0\win10-x64\AppPackages\MyProject_1.0.0.0_Test\MyProject_1.0.0.0_x64.cer"
$sign = Start-Process -NoNewWindow -FilePath $SignTool -PassThru -ArgumentList $arguments.ToArray() -RedirectStandardOutput "C:\Logs\SignLog.txt"
Wait-Process -InputObject $sign
命令行
或者您可以在命令行中使用
dotnet publish
命令来发布您的应用程序。同样,将 D4E5F6... 替换为您的 EV 代码证书指纹。并将 CertificatePassword 替换为您证书的密码(尽管我建议使用上面的 PowerShell 方法来确保密码不在您的 CLI 历史记录中)
几个注意事项:
-f
并删除 /p:GenerateAppxPackageOnBuild=true
/p:PackageCertificatePassword
绕过 EV 代码证书(例如 SafeNet 身份验证客户端)的弹出窗口。为此使用 PowerShell 方法dotnet publish C:\MyProject\MyProject.csproj -c Release -f net6.0-windows10.0.19041.0 /p:GenerateAppxPackageOnBuild=true /p:AppxPackageSigningEnabled=true /p:PackageCertificateThumbprint="D4E5F6..." /p:PackageCertificatePassword="CertificatePassword"