问题描述
我们正在从本地生成服务器迁移到Azure Pipelines.我们生产收缩包装"台式机软件,因此很明显,我们需要在发布所有二进制文件之前对其进行签名.我们当前的构建基础架构使用GlobalSign的USB硬件令牌来完成此操作,但是显然,当我们进行云构建时,这是行不通的-可悲的是,云未配备USB端口:D
We're in the process of moving from on-premise build servers to Azure Pipelines. We produce "shrink-wrap" desktop software so clearly we need to sign all our binaries before releasing. Our current build infrastructure does this using a USB hardware token from GlobalSign, but clearly that isn't going to work when we're doing cloud builds - sadly, clouds are not equipped with USB ports :D
现在,GlobalSign最近开始以广告 Azure Key Vault作为密钥存储选项,他们非常乐意将其出售给我们,但是我不确定我们如何将其实际与构建管道集成(或者甚至是否有可能).
Now, GlobalSign has recently started advertising Azure Key Vault as a key storage option, and they're perfectly happy to sell this to us, but I'm not sure how we'd actually integrate that with our build pipelines (or indeed whether that's even possible).
有人真的做了这项工作吗?
Has anyone actually made this work?
推荐答案
我一直在与Azure Key Vault和Azure Pipelines进行斗争,以使我们的代码签名并获得成功.所以这就是我发现的东西.
I've been battling with Azure Key Vault and Azure Pipelines to get our code signed, and succeeded. So here's what I found out.
至关重要的是,用于代码签名的扩展验证(EV)证书与普通" SSL证书完全不同.可以根据需要任意导出标准文件,这意味着您可以将其上传到Azure Pipelines并与标准Microsoft Sign Tool一起使用.
Critically, Extended Validation (EV) certificates used for code signing are very different animals to 'normal' SSL certificates. The standard ones can be exported as much as you like, which means you can upload it to Azure Pipelines and use it with the standard Microsoft Sign Tool.
但是,一旦将EV证书放入Azure Key Vault,它就不会以任何通常的方式发出.您必须使用 Azure签名工具从管道中调用它./stackoverflow.com/a/57490154/5363308>上方的Anodyne
However, once an EV certificate is in Azure Key Vault, it isn't coming out in any usual fashion. You must call it from Pipelines using the excellent Azure Sign Tool as discovered by Anodyne above
将您的证书放入Key Vault.您可以使用任何您喜欢的证书颁发机构来生成证书,只要他们了解您将需要EV证书,并且至关重要的是,它具有硬件安全模块(HSM)和不是带有物理USB密钥的一个.任何基于云的系统(例如Key Vault)都需要HSM版本.
Get your certificate into Key Vault. You can use any certificate authority you like to generate the certificate, as long as they understand that you'll need an EV certificate, and critically one that has a hardware security module (HSM), and not one with a physical USB key. Any cloud based system like Key Vault will need an HSM version.
要获得从外部访问此证书的权限,可以跟踪此页面,但当心,它错过了一步.因此,请先阅读该文档,然后阅读以下概述的步骤,以设置Key Vault:
To get the permissions to access this certificate externally you can follow this page but beware it misses a step. So read that document first, then these summarised steps, to get the Key Vault set up:
- 打开Azure门户,转到
Azure Active Directory
区域,然后创建一个App registration
:输入一个令人难忘的名称,忽略Redirect URI
,然后保存它. - 转到特定的
Key Vault
,然后依次为Access control (IAM)
和Add role assignment
.在select
输入框中输入刚创建的应用程序的名称.另外选择一个Role
,我建议Reader
,然后保存. - 缺少的部分:仍然在Key Vault中,单击
Access policies
菜单项.单击Add Access Policy
并添加您的应用程序.Certificate Permissions
需要打勾Get
.尽管您可能在此保管库中根本没有任何键,但Key Permissions
仍需要具有Get
和Sign
.您会以为这两个将在证书烫发中... - 返回到刚创建的应用程序.选择
Certificates & secrets
,然后选择上载证书(纯粹是用于远程访问Key Vault的新证书)或创建client secret
.如果是后者,请保留密码的副本,您将不会再看到它! - 在应用程序的
Overview
部分中为Application (client) ID
.这以及密码或证书,将在稍后的管道任务中提供给Azure Sign Tool.
- Open the Azure portal, go to the
Azure Active Directory
area, and create anApp registration
: put in a memorable name, ignore theRedirect URI
, and save it. - Go to your specific
Key Vault
, thenAccess control (IAM)
, thenAdd role assignment
. Type the name of the app you just created into theselect
input box. Also choose aRole
, I suggestReader
and then save. - The Missing Part: Still in the Key Vault, click the
Access policies
menu item. ClickAdd Access Policy
and add your application. TheCertificate Permissions
need to have theGet
ticked. And theKey Permissions
, despite the fact that you may not have any keys at all in this vault, need to haveGet
andSign
. You would have thought these two would be in the certificate perms... - Go back to the application you just created. Select the
Certificates & secrets
, and either choose to upload a certificate (a new one purely for accessing the Key Vault remotely) or create aclient secret
. If the latter, keep a copy of the password, you won't see it again! - In the
Overview
section of the app will be theApplication (client) ID
. This, and the password or certificate, is what will be fed to the Azure Sign Tool later on in a Pipelines task.
从Azure处理实际的代码签名需要许多步骤.以下内容适用于Microsoft托管的代理,尽管类似的问题将影响您拥有的任何私人代理.
Handling the actual code signing from Azure requires a number of steps. The following applies to Microsoft hosted agents, although similar issues will affect any private agents that you have.
-
Azure Sign Tool需要安装.NET Core SDK,但至少应为2.x版本,并且由于最新 .NET Core SDK为始终使用,这意味着只要Windows版本足够最新,您不需要自己安装.您可以看到 SDK随Windows代理一起提供.
The Azure Sign Tool needs the .NET Core SDK to be installed, but a version that's at least version 2.x, and since the latest .NET Core SDK is always used, this means as long as the version of Windows is current enough, you don't need to install it yourself. And you can see which version of the SDK is shipped with which Windows agent.
在撰写本文时,Azure Pipelines中的当前Hosted
操作系统版本(也称为Default Hosted
)是Windows Server 2012 R2.这还不是最新的.要解决此问题,安装更新的.NET Core SDK会拖累每个版本,尽管安装可行,但调用Azure Sign Tool可能无法正常工作.似乎只能找到较旧版本的SDK,并引发以下错误:Unable to find an entry point named 'SignerSignEx3' in DLL 'mssign32'.
The current Hosted
OS version in Azure Pipelines, also called Default Hosted
, is, at the time of writing, Windows Server 2012 R2. Which isn't up to date enough. Installing a newer .NET Core SDK to overcome this is a time drag on every build, and although the installation works, calling the Azure Sign Tool may not work. It seems to be finding only older versions of the SDK, and throws this error: Unable to find an entry point named 'SignerSignEx3' in DLL 'mssign32'.
因此,最简单的方法是将您的构建更改为使用更高版本的OS映像. Windows 2019就像一个魅力.无需安装任何版本的.NET Core.
So the easiest thing to do is change your build to use a later OS image. Windows 2019 works like a charm. And there is no need to install any version of .NET Core.
然后创建一个命令行任务以安装Azure Sign Tool.您也可以使用.NET Core CLI任务,但是没有必要.在任务中,键入以下内容:
Then create a command line task to install the Azure Sign Tool. You can use a .NET Core CLI task as well, but there is no need. In the task, type this:
set DOTNET_SKIP_FIRST_TIME_EXPERIENCE=true
dotnet tool install --global AzureSignTool --version 2.0.17
自然使用所需的任何版本.
Naturally using whichever version that you want.
DOTNET_SKIP_FIRST_TIME_EXPERIENCE环境变量不是严格必需的,但是设置它可以使事情加速很多(请参阅此处以获取解释).
The DOTNET_SKIP_FIRST_TIME_EXPERIENCE environment variable isn't strictly necessary, but setting it speeds things up quite a bit (see here for an explanation).
最后,创建另一个命令行任务,然后键入要与之一起运行的Azure Sign Tool命令.在Windows上,这类似于以下内容,请注意使用^
而不是/
作为行继续标记.当然,请参阅此处以获取更多参数信息:
Finally, create another command line task and type in the Azure Sign Tool command that you wish to run with. On Windows this would be something like below, note with ^
not /
as a line continuation marker. Naturally, see here for more parameter information:
AzureSignTool.exe sign -du "MY-URL" ^
-kvu https://MY-VAULT-NAME.vault.azure.net ^
-kvi CLIENT-ID-BIG-GUID ^
-kvs CLIENT-PASSWORD ^
-kvc MY-CERTIFICATE-NAME ^
-tr http://timestamp.digicert.com ^
-v ^
$(System.DefaultWorkingDirectory)/Path/To/My/Setup/Exe
理论上,您应该成功!签名工具的输出效果相当好,通常可以将问题定位在哪里.
And in theory, you should have success! The output of the sign tool is rather good, and usually nails where the problem is.
这篇关于如何使用Azure Key Vault中的证书/密钥对使用Azure Pipelines构建的代码进行签名?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!