IEInternals

A look at Internet Explorer from the inside out. @EricLaw left Microsoft in 2012, but was named an IE MVP in '13 & an IE userAgent (http://useragents.ie) in '14

Everything you need to know about Authenticode Code Signing

Everything you need to know about Authenticode Code Signing

  • Comments 27

In today’s post, I’ll be discussing the use of Authenticode to sign software programs; this post will be of interest primarily to software developers. Large software companies (like Microsoft) often have an entire team dedicated to the code-signing and release process, but even (especially) small software publishers should sign their code. In this post, I’ll explain why, and tell you everything you need to do to achieve the benefits of shipping signed code.

Why sign your code?

As a software publisher, there are two reasons to sign your code:

  1. To prove its Integrity
  2. To develop its Reputation

The first point is simple: digitally signing your code helps to ensure that it cannot be tampered with, either on your servers, or when it is being downloaded to a user’s computer, especially over an insecure protocol like HTTP or FTP. This provides the user the confidence of knowing that the program they’ve just downloaded is the same one that you built.

Of course, that Integrity alone doesn’t mean a lot. Malicious files can also be signed, and a signature from, say, Bad-Guys-R-Us doesn’t mean that the code is safe to run. That’s where Reputation comes in. Historically, major software publishers like Microsoft, Adobe, Apple, IBM, etc, have worked hard to develop a good reputation in the minds of users. A user who downloads an application signed by Microsoft is usually more likely to trust and install that program than if the program were unsigned, or signed by some company they’ve never heard of. One problem with this scheme is that it doesn’t work too well except for the biggest of publishers—if I’ve never heard of Just Great Software, should I trust a package that bears their signature?

Internet Explorer 9’s SmartScreen Application Reputation feature helps level the playing field. This feature uses a variety of signals to evaluate the reputation of a given download, including the download history and popularity, anti-virus results, reputation of the site it has been delivered from, and more. As a small software publisher, the best way to accumulate your good reputation and allow it to benefit all of your software is to digitally sign your code. Signing your code allows the SmartScreen Application Reputation service to recognize a program’s origins, and allow that origin information to influence the reputation of the program. Small publishers benefit the most from this. For instance, while most users have never heard of me, my freeware programs are digitally signed by my certificate, and the clean reputation for my certificate means that SmartScreen Application Reputation can identify them as non-malicious.

When SmartScreen recognizes non-malicious code, the user benefits from a more streamlined trust experience, and fewer security prompts are shown when downloading and running the program. In contrast, unsigned and unknown programs are treated with suspicion and show more security warnings; our data indicates that 25-40% of such programs are eventually determined to be malicious.

Of course, if I were to ever abuse my good reputation to sign and release malicious code, the SmartScreen system can easily revoke my good reputation—my certificate’s signature would turn from a badge of honor into a flashing signal of untrustworthy software.

Hopefully, I’ve convinced you that signing your code is the right way to go. Now, on to the “how-to” portion of this post.

Step 1: Acquire a Software Publisher’s Digital Certificate

The first step is to get a software publisher’s certificate. Internally, these certificates are slightly different than a HTTPS server certificate (they bear different usage flags), and often cost a bit more because the certificate authority will perform more due diligence in verifying your identity. Certificates are issued by Certificate Authorities (CAs), firms whose job it is to verify the identity of certificate requestors and issue cryptographically-protected certificates that map the private key (which only you know) to a public key (which is contained in the certificate itself).

I purchased my personal Software Publisher’s certificate from Comodo via TuCows, a reseller. Their current prices are $75 for a certificate valid for one year, $140 for two years, or $195 for three years. Generally speaking, it’s a good idea to buy a certificate with the longest possible validity period because renewing certificates is not a fun experience, and it also helps to mitigate the problem of certificate rollover. Certificate rollover occurs when your old certificate expires and you begin signing your code with a new replacement certificate; all of your reputation was accumulated against the old certificate, and hence there may be a time lag for your new certificate to acquire a good reputation.

The process of acquiring a certificate typically takes a few days, and for non-incorporated software publishers like me, requires a fair amount of personal information. For instance, the validation process required that I fax a copy of my drivers license and a few utility bills to the Certificate Authority, so there was reasonable proof of my identity. I also validated my phone number and spoke to a representative. If I were to ever “go rogue” and start using my certificate for evil, I’m sure the terms of service say that this information would be provided to law enforcement so they could come ask me some questions.

After the verification process was completed, I was given the opportunity to download my new certificate. When downloading your new certificate, you should follow the Certificate Authorities instructions exactly as there are some mistakes that can be very difficult to recover from. In particular, choose a memorable but strong password to protect your private key file. After you have your certificate, be very sure to protect the private key file—if you lose control of your private key, a bad guy could sign code using your certificate. If your certificate is used maliciously, bad reputation will taint everything you’ve ever signed!

Note: Yes, you can also generate a self-signed certificate, but this is only useful if your software will never be used outside of your organization. Inside your organization, you could use Group Policy to deploy your self-signed certificate to all clients so that they trust it. However, any PC that isn’t configured to trust your certificate will block your software as bearing an invalid signature. Unless your company already has an internal PKI (public key infrastructure) deployment, you’re better off getting a publisher certificate that chains to one of the Trusted Root CAs.

Note: In August 2012, Microsoft announced support for a new type of Code-Signing certificate, the Extended Validation (EV) certificate. These certificates tend to be more expensive and harder-to-use (requiring security token hardware) but have the benefit of providing faster accumulation of reputation for SmartScreen.

Step 2: Sign your code

After you have a certificate, you can begin signing your installation executables or MSI install packages. Because you’ll want to do this for every build that you release, automating as much of the signing process as possible using a script or batch file is highly recommended.

Note: The .NET Framework has a different type of code-signing called “Strong Naming”. A strong name is not recognized by anything in Windows except the .NET Framework, and hence I won’t discuss it further here. ShawnFa wrote a good article explaining Strong Names and Authenticode.

To sign your program using Authenticode, you can use the SignCode.exe utility which shipped with the Microsoft .NET Framework version 1.1:

signcode -spc \src\mycert.spc -v \src\mykey.pvk -n "Fiddler2 Web Debugger (Beta)" -i "http://www.fiddler2.com/fiddler2/" -a sha1 -t http://timestamp.comodoca.com/authenticode Fiddler2BetaSetup.exe

You’ll be prompted to enter the password for your PVK file, and after doing so, your program will be signed and time-stamped.

The –n parameter specifies the string that will be shown in the “Name” field identifying the software. The –i parameter specifies the URL that will be launched if the user clicks on the Name hyperlink. The –a parameter specifies which hash algorithm should be used—this should always be sha1 because older hash algorithms are less secure, and will eventually be retired. Internet Explorer on Windows 7 SP1, for instance, disables MD2/MD4 hashes and treats signatures using those algorithms as invalid. The –t parameter specifies the URL of the time-stamping server, discussed later.

These inputs result in a signature that is displayed by various trust prompts like so:

Dialog box showing signature information

Alternatively, you can use the SignTool.exe shipped in the Windows SDK and later versions of the .NET Framework. To use this tool, you’ll need to convert your .SPC & .PVK files into a new PFX file, which you can do from a Visual Studio Command prompt:

pvk2pfx -spc mycert.spc -pvk mykey.pvk -pfx mycert.pfx -pi PVKPassword -po NewPFXPassword

After that, you can use a script like the following to sign your package:

set /P PFXPass=Enter PFX Password:
signtool sign /p %PFXPASS% /f C:\src\mycert.pfx /d "FiddlerCap" /du "
http://www.fiddlercap.com/" /t http://timestamp.comodoca.com/authenticode /v FiddlerCap-en.msi
set PFXPass=blank

Easy, huh?

Best Practice: Sign both the installer and the application

When downloading installation packages from the Internet, the browser and/or Windows Shell will only check the digital signature on the installer itself. However, as a best practice, you should also sign the main executable of your application as well. This helps prevent tampering, but more importantly, it helps ensure that any security tools on the user’s machine can more readily identify your code. For instance, many anti-malware or firewall tools will treat unsigned executables with suspicion, and may even block them if they happen to share the same filename as a malicious program. For instance, one of my utilities, SlickRun shared the same filename (sr.exe) as a malicious program, and some anti-malware tools were too primitive to recognize the false positive. However, after I signed sr.exe directly, this problem went away. Similarly, some firewalls assign exceptions to programs based on their digital signature or file hash. If the user approves an exception to allow your program through the local firewall, that exception may be deleted if your program is later updated and the file’s hash changed. Signing your code can help prove to the firewall that the new version of your program should inherit the exemption granted to the older version.

Note: Typically, Windows does not itself check the digital signature when running a locally-installed version of your program; it only checks the signature when the program bears a Mark-of-the-Web indicating that it was downloaded from the Internet or extracted from an archive downloaded from the Internet. However, executables written in .NET can be an exception to this. The .NET Framework has the ability to assign security permissions to code based on its signature, called “publisher evidence.” Doing so necessitates that the signature be verified, and verifying the signature may require an expensive network request to check the certificate for revocation. If you are not using the “publisher evidence” feature of .NET, you can modify your application’s manifest to indicate that .NET should not check the signature.

YourApp.exe.config:

<configuration> 
 <runtime> 
 <generatePublisherEvidence enabled="false"/> 
 </runtime> 
</configuration>

 

Best Practice: Time-stamping

When signing your code, you have the opportunity to timestamp your code; you should definitely do this. Time-stamping adds a cryptographically-verifiable timestamp to your signature, proving when the code was signed. If you do not timestamp your code, the signature will be treated as invalid upon the expiration of your digital certificate. Since it would probably be cumbersome to re-sign every package you’ve shipped when your certificate expires, you should take advantage of time-stamping. A signed, time-stamped package remains valid indefinitely, so long as the timestamp marks the package as having been signed during the validity period of the certificate.

 

Thanks for helping ensure a secure and streamlined experience for Windows users!

-Eric

Update: Not all publisher certificates are enabled to permit timestamping to provide indefinite lifetime. If the publisher’s signing certificate contains the lifetime signer OID (OID_KP_LIFETIME_SIGNING 1.3.6.1.4.1.311.10.3.13), the signature becomes invalid when the publisher’s signing certificate expires, even if the signature is timestamped. This is to free a Certificate Authority from the burden of maintaining Revocation lists (CRL, OCSP) in perpetuity.

Update: It also appears that some CAs do not provide SPC and PVK files, instead providing the certificate in a different format. You can convert from a .CER file to a SPC file using Cert2SPC.exe in the Windows SDK. If you have a PEM file instead of a .PVK file, you can convert that using OpenSSL's pvk command: pvk -in PEM_KEY_FILE -topvk -out PVK_FILE. http://help.godaddy.com/article/6034 has a step-by-step walkthrough.

Curious about where the Authenticode signature actually goes into the binary? See this whitepaper.

Update: Some developers use tricks to sneak unauthenticated data inside Authenticode-signed binaries. You shouldn't do that.

  • @Jack: Certificates are trusted by Windows, not IE. Having said that, I'm not aware of any change to GoDaddy's certificate status in the last few years.

  • What do you do when your current certificate is expiring and you need a new one?  Can my reputation from the old certificate be transferred to the new one? And, how long does it take to get a rep?

  • @Peter Weyzen: Rollover is indeed a challenge with reputation systems; that's one reason why it's generally a good idea to get a certificate with a validity period of multiple years.

    EV Code-signing certificates were introduced to address the challenge of reputation rollover; please see blogs.msdn.com/.../microsoft-smartscreen-amp-extended-validation-ev-code-signing-certificates.aspx

    Reputation building time is subject to many factors, including the popularity of the download.

  • Hi Eric, but if a certificate is outdated, the app will stop working? Thanks for the post.

    [EricLaw] This is discussed in the post. To wit: Typically, Windows does not itself check the digital signature when running a locally-installed version of your program; it only checks the signature when the program bears a Mark-of-the-Web indicating that it was downloaded from the Internet or extracted from an archive downloaded from the Internet.

  • Great article.  I have code signed my EXE (as well as all related DLLs) with a valid COMODO code signing certificate.  But when I run the program from a network folder, I still receive a warning saying "We can't verify who created this file.  Are you sure you want to run this file?"  I've checked the file's properties and it shows the program is signed (on the digital signatures tab).  

    The file is located in a folder on my home network running on an XP machine.  I am calling the EXE from my Win7 machine.

    Any thoughts what I've missed?

    [EricLaw] If you copy the file to your desktop, do you see the same prompt? In Spring 2013, the Windows team made a change such that anything executed from a network share will show a prompt even if validly signed.

  • Eric, no the application runs without warning on my desktop. You are correct.  I've tried running some commercial EXE's from the network PC and do get the same warning.  

    I'm hoping I don't understand the term "network share".  Would this same error appear on computers running the program on a "real" server?  I may have to make significant changes to my deployment strategy.  (Currently I'm putting the EXE/DLLs in a shared folder on the server with data in a sub folder.)

    [EricLaw] If the app is launched using a path of something like \\server\apps\app1.exe, the prompt will show (prompting for that scenario isn't new, but in the old days, the signature dialog would show the signing information instead of the generic warning).

    Thanks.

  • What all do we need to provide to certifying authority to get the certificate? In some blogs i read that we need to send our public key.. Is it so? If so, where and how to get that public key?

    [EricLaw] Typically, when you buy a certificate from a CA site, the site will use an ActiveX control (like http://blogs.msdn.com/b/ieinternals/archive/2010/05/14/certificate-enrollment-xenroll-vs-certenroll-activex-object.aspx) to generate a public/private key pair locally, and then send a certificate request to the CA. The CA never gets your private key, which is kept on your PC.

    What are all the files we will get from certifying authority? We will get only .spc file or anything else? In this blog, while signing code using signcode.exe, you have mentioned .pvk file.. where do we get that .pvk file? Thanks.

    [EricLaw] Typically, the PVK file is exported from your Windows certificate store, where it was placed when the ActiveX control generated it.

     

  • Couple of questions

    1. I can not find anything that says Windows checks the signatures on all the DLL used by an EXE.

    [EricLaw] Generally speaking, Windows does not check the signatures on DLLs when loaded by an executable. There are exceptions (e.g. DRM-related DLLs, and all modules are signature checked on WindowsRT/ARM).

    2. AppLocker has a way to say only allow running signed executable files, but that is not much use if the DLL used by the EXE are not also checked.

    [EricLaw] You'd have to ask the AppLocker team about their threat model on that. Perhaps they enforce a signature check or perhaps there's a reason that this is outside of their scope.

    3. When I look at the Windows DLL our application uses, I find that 3 of 32 are signed.  Why doesn't Microsoft sign all DLL they deliver?

    [EricLaw] Which DLLs specifically? It's important to understand that many Windows binaries are "catalog signed" instead of having an Authenticode signature directly embedded into the file.

  • Signage On Windows 7 Professional using Visual Studio 2013 compiling for 64-bit release mode, dependency walker says the below DLL are referenced but "signtool verify /pa" says only ntdll.dll is signed.

    c:\windows\system32\ADVAPI32.DLL
    c:\windows\system32\API-MS-WIN-DOWNLEVEL-ADVAPI32-L1-1-0.DLL
    c:\windows\system32\API-MS-WIN-DOWNLEVEL-NORMALIZ-L1-1-0.DLL

    ... 

    Thanks for the quick response to the previous post.

    [EricLaw] As I mentioned, most Windows files are catalog-signed instead of carrying an Authenticode signature directly in the binary. See http://technet.microsoft.com/en-us/sysinternals/bb897441.aspx.

    For instance:

    C:\tools>sigcheck c:\windows\system32\advapi32.dll

    Sigcheck v2.03 - File version and signature viewer
    Copyright (C) 2004-2014 Mark Russinovich
    Sysinternals - www.sysinternals.com

    c:\windows\system32\advapi32.dll:
            Verified:       Signed
            Signing date:   12:38 PM 2/23/2014
            Publisher:      Microsoft Windows
            Description:    Advanced Windows 32 Base API
            Product:        Microsoft« Windows« Operating System
            Prod version:   6.3.9600.16384
            File version:   6.3.9600.16384 (winblue_rtm.130821-1623)
            MachineType:    64-bit

     

  • We have now purchased two code signing certificates from Comodo with no apparent change in the download experience for our users.  We keep being told it is a matter of time yet our application never seems to develop a sufficient reputation to be treated as safe.

    What do we need to do to get our app to be treated as safe?  The certificate cost us more than $300 for the two years and we did not get anything for it.  Talking with Comodo they tell us they cannot help us figure out why it never does what it is supposed to do.  My email - and I would desperately like a reply - is jim at x-gecko.com

    Thanks!

  • If I release updates to my software and change the name of the download from say myApplicationSetup_1.2.exe to myApplicationSetup_1.3.exe, does that impact the reputation of the download? Does the file name and location of the file gain reputation or is it the certificate that has signed the file?

    [EricLaw] Positive reputation does not accrue to a URL, so changing the filename won't cause it to lose reputation. If the file is signed, the certificate's reputation is evaluated. If it's not signed, then any change to any byte of the file resets its reputation (since it's based on hash).

  • Hi, is I am a download SDK provider, an Installer, who signs the package? The software published or the Installer?

Page 2 of 2 (27 items) 12
Leave a Comment
  • Please add 1 and 2 and type the answer here:
  • Post