How do I securely configure a CI server to digitally sign binaries?

邮差的信 提交于 2019-12-02 20:44:27

I ended up doing a very similar approach to what @GiulioVlan suggested, but with a few changes.

MSBuild Task

I created a new MSBuild task that executes signtool.exe. This task serves a couple main purposes:

  • It hides the password from ever being displayed
  • It can retry against the timestamp server(s) upon failures
  • It makes it easy to call

Source: https://gist.github.com/gregmac/4cfacea5aaf702365724

This specifically takes all output and runs it through a sanitizer function, replacing the password with all *'s.

I'm not aware of a way to censor regular MSBuild commands, so if you pass the password on commandline directly to signtool.exe using it will display the password -- hence the need for this task (aside from other benefits).

Password in registry

I debated about a few ways to store the password "out-of-band", and ended up settling on using the registry. It's easy to access from MSBuild, it's fairly easy to manage manually, and if users don't have RDP and remote registry access to the machine, it's actually reasonably secure (can anyone say otherwise?). Presumably there are ways to secure it using fancy GPO stuff as well, but that's beyond the length I care to go.

This can be easily read by msbuild:

$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\1 Company Dev@CodeSigningCertPassword)

And is easy to manage via regedit:

Why not elsewhere?

  • In the build script: it's visible by anyone with source code
  • Encrypted/obfuscated/hidden in source control: if someone gets a copy of the source, they can still figure this out
  • Environment variables: In the Teamcity web UI, there is a detail page for each build agent that actually displays all environment variables and their values. Access to this page can be restricted but it means some other functionality is also restricted
  • A file on the build server: Possible, but seems a bit more likely it's inadvertently made accessible via file sharing or something

Calling From MSBuild

In the tag:

<Import Project="signtool.msbuild.tasks"/>

(You could also put this in a common file with other tasks, or even embed directly)

Then, in whichever target you want to use for signing:

<SignTool  SignFiles="file1.exe;file2.exe" 
   PfxFile="cert.pfx" 
   PfxPassword="$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\1 Company Dev@CodeSigningCertPassword)"
   TimestampServer="http://timestamp.comodoca.com/authenticode;http://timestamp.verisign.com/scripts/timstamp.dll" />

So far this works well.

One common technique is to leave keys and certificates in Version Control, but protect them with a password or passphrase. The password is saved in environment variables local to the machine, which can be easily accessed from scripts (e.g. %PASSWORD_FOR_CERTIFICATES%).

One must be careful not to log these values in plain text.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!