Signing .NET assemblies without exposing the snk file publicly

jcw's Avatar


10 Mar, 2014 07:46 AM

I would like to sign my .NET assemblies generated by my CI build. However, I don't want to make the SNK file (which contains the private key) publicly available. From what I've read in the documentation, I'm considering the following approach:

  1. Add an environment variable to appveyor.yml that contains the binary SNK file (roughly 3 KB) as a base-64 encoded string which is encrypted using Account -> Encrypt data.
  2. In after_build, execute a script to re-hydrate the SNK file from the automatically decrypted environment variable, and then invoke the visual studio tool "sn -R" to sign the assemblies.

Is this a reasonable approach, or perhaps there is a better one that comes to mind?

My concerns with this approach:

  • The amount of text might exceed limitations imposed on environment variables
  • I'm assuming the visual studio tool "sn" would be available for scripting on the build VM
  1. Support Staff 1 Posted by Feodor Fitsner on 10 Mar, 2014 05:43 PM

    Feodor Fitsner's Avatar

    I would use the following approach:

    1. Encrypt .snk file contents using symmetric algorithm.
    2. Put encrypted .snk into repository.
    3. During the build get passphrase used to encrypt .snk file from environment variable and decrypt .snk file.

    1. You can encrypt files of any length.
    2. Environment variable holds passphrase only.

    Encrypt/decrypt example for PowerShell: (in your case it would be even shorter as you work directly with file stream, not strings).

    sn.exe is part of Windows SDK which is installed on build servers. You may find this and other utilities in C:\Program Files (x86)\Microsoft SDKs\Windows\v8.1A\bin\NETFX 4.5.1 Tools folder.

  2. 2 Posted by jcw on 11 Mar, 2014 07:04 AM

    jcw's Avatar

    That's a great generalized approach, thanks!

    It looks like I can include a pfx (a password protected certificate) in the source and then invoke a command to digitally sign the exe with the password for the certificate specified in the command line. I'm considering doing this instead of strong-name signing.


    1. Are commands/scripts specified in the UI for something like after_build publicly visible, either directly or through build reports/logs? These being only visible to build administrators would be necessary if I embed it directly in the command.
    2. I tested adding an encrypted value to an appveyor.yml file (contains 3 lines in total) and now all of my build configuration in the UI is being ignored - I was expecting this, since I recall reading it somewhere. However, I thought I would double-check - can you confirm that leveraging the encrypted value functionality of Tools -> "Encrypt data" requires switching completely to an appveyor.yml file?
  3. Support Staff 3 Posted by Feodor Fitsner on 11 Mar, 2014 06:00 PM

    Feodor Fitsner's Avatar

    Answers to your questions:

    1. Yes, those scripts are visible in build log. But I guess it's not a problem unless only logic are being put there, not a sensitive info. Definitely, knowing crypt/decrypt algorithm does not help if you don't know a key/passphrase ;)

    2. Not necessary, you can put your sensitive data to environment variables ("Environment" tab). Those variables are not shown in the build log.

    So, the general approach for your solution would be:
    1. Put signing function into, let's say "Install" or "Befor build" scripts sestion.
    2. Set certificate password to environment variable on Environment tab.
    3. Use this variable in the script to sign exe.

    Let me know if you have any questions.

  4. Ilya Finkelshteyn closed this discussion on 25 Aug, 2018 01:37 AM.

Comments are currently closed for this discussion. You can start a new one.

Keyboard shortcuts


? Show this help
ESC Blurs the current field

Comment Form

r Focus the comment reply box
^ + ↩ Submit the comment

You can use Command ⌘ instead of Control ^ on Mac