4

Here's our story: We're developing some software (written in C#/.NET) and we're already signing the assemblies with strong names, I do this in Visual Studio with a pfx file that is protected by a password.

As an added security step I would like to sign the assemblies or at least the executable with Authenticode.

The problem is: The targets for our deployment will not have internet access nor are we able to get our own CA verified certificate at the moment. We have complete control over the target of deployment during the deployment phase, we choose the hardware, install the OS etc., but once our product (which is thus a combination of hard- and software) is "out there" we would like to provide as much security as we can.

Of course we understand that we can't control what happens to it in the wild, but we have also taken measures to be able to see if the hardware has been tampered with. If it has, we know we can't trust the software and we won't look it.

To get back around to our main issue: Does it make sense to create our own "fake" (non-verifiable) certificate to sign the assemblies? Do we need to put these certificates into the Windows store? I'm trying to protect our executables from being replaced by other executables, say through a USB-flash drive or something similar.

What's the best way to deal with this problem? Thanks in advance.

Davio
  • 143
  • 1
  • 4

1 Answers1

10

When code is signed with Authenticode, Windows checks the signature with regards to the public key contained in the embedded certificate, and that certificate is validated with regards to the "trusted CA" that the OS maintains in the "Root" store. Adding a custom CA to that store is highly feasible for anybody with Administrator rights on the machine (and this more or less includes anybody who has physical access to the machine). Signing your code protects against anything only if we assume that the attacker will not be able to recompute a fake signature relative to a fake certificate that would link to one of the trusted CA.

Ergo, signing the code will not prevent alterations from people who have access to the machine. This is a very generic situation, by the way: preventing alteration of software by the people who physically own the hardware has been the Holy Grail for game vendors and media content publishers. Somewhat limited success has been achieved with closed hardware (e.g. game consoles) but on a PC, this is doomed. (Some people are working on a way to do it but that turns out to be hard, both technically and politically.)

At best, your code signing may prevent silent alteration from attackers who do not bother producing fake certificates (i.e. some low-grade malware), but determined attackers will not be deterred.

Note: code signing might have legal benefits, though: if code signing is enforced, this might help in proving, during a trial, that whoever modified the code was fully aware that it was forbidden by the license. Don't take my word for it, though, because I am not a lawyer and any law-related answer is unlikely to be valid for all the legal systems which exist worldwide (there are about 200 sovereign states, after all, hence at least that many legal systems which are nominally independent from each other).

Thomas Pornin
  • 320,799
  • 57
  • 780
  • 949
  • Actually there is a online component but it is not required. If you want the authenticode signature to not give expiration warnings when the expiration date passes you must use a time-stamp server where the sigiture on the timestamp must also be signed by a trusted root (for simplicity most public CA's provide a [time-stamp server](http://timestamp.verisign.com/scripts/timstamp.dll) and you can just have the same CA for your cert and the cert's time-stamp). See the [Trusted Timestamping](http://en.wikipedia.org/wiki/Trusted_timestamping) article on Wikipedia for more info. – Scott Chamberlain Jan 04 '13 at 21:03
  • If you forgo the time-stamp Autenticode will still work. However your end users will get a invalid signature error after the expiration date on the certificate. This is to prevent somone from stealing a old expired certificate from you, temporarily rolling back the clock on their computer, and signing a malicious exe with your old expired certificate. – Scott Chamberlain Jan 04 '13 at 21:06