Windows Code Signing: A Comprehensive How-To Guide

Code signing is an essential step in distributing executables on Windows. By signing your binaries, you not only enhance user trust but also reduce or eliminate Windows SmartScreen warnings. This guide covers the entire process—from obtaining a certificate to signing applications built in Rust, C#, and other languages.


Table of Contents


Introduction

Windows employs measures such as SmartScreen to protect users from potentially unsafe software. Unsigned executables may trigger warnings, leading to a poor user experience. Code signing not only verifies your application's authenticity but also builds its reputation over time, making distribution smoother.


Prerequisites

Before you begin, ensure you have:

  • A Windows machine with the Windows SDK installed.
  • Access to the Developer Command Prompt (installed with the Windows SDK).
  • Basic command-line familiarity.
  • Your executable file ready for signing.

Obtaining a Code Signing Certificate

Code signing certificates come in two main types:

  • OV (Organization Validation): Requires verification of your organization and is generally more affordable.
  • EV (Extended Validation): Involves a stricter verification process, often including a hardware token, and generally bypasses SmartScreen warnings more quickly.

Steps:

  1. Research Providers: Look into trusted providers like DigiCert, Sectigo, or SSL.com.
  2. Purchase a Certificate: Prices typically range from $60 to $100 per year for OV certificates.
  3. Receive Your Certificate: You'll most likely receive a .pfx file containing your certificate and private key.

Places to buy a code signing certificate.

Here are a couple options.


Installing the Certificate

Once you have your .pfx file:

  1. Import the Certificate:

    • Double-click the .pfx file.
    • Follow the Certificate Import Wizard to add the certificate to the Personal store.
  2. Using an EV Certificate:

    • If your certificate comes with a USB token or similar hardware, ensure it is properly connected and configured according to the provider's instructions.

Signing Your Executable with Signtool

The Windows SDK includes a tool called signtool.exe, which is used for signing executables.

Basic Command

Open the Developer Command Prompt and execute:

signtool sign /fd SHA256 /tr http://timestamp.digicert.com /td SHA256 /f your-cert.pfx /p your-password your_executable.exe

  • /fd SHA256: Specifies the file digest algorithm.
  • /tr http://timestamp.digicert.com: URL of the timestamp server.
  • /td SHA256: Specifies the digest algorithm for the timestamp.
  • /f your-cert.pfx: Path to your code signing certificate.
  • /p your-password: Password for your certificate file.
  • your_executable.exe: The executable file you want to sign.

Advanced Options

You can explore additional flags such as:

  • /as: Append the signature if one already exists.
  • /debug: Enable debugging output.

Verifying the Signature

To ensure your executable is signed correctly, run:

signtool verify /pa your_executable.exe

This command checks that the signature is valid and trusted by the system.


Signing a Rust Executable

If you have a Rust project and want to sign its compiled binary, follow these steps:

  1. Compile Your Rust Application:
    • Use Cargo to build your project:
     cargo build --release
  • Your executable will be located in the target/release/ directory.
  1. Sign the Rust Executable:
    • Use the same signtool command to sign the binary:
     signtool sign /fd SHA256 /tr http://timestamp.digicert.com /td SHA256 /f your-cert.pfx /p your-password target/release/your_rust_app.exe
  1. Verify the Signature:
    • Confirm the signature using:
     signtool verify /pa target/release/your_rust_app.exe

This ensures that your Rust application is properly signed and trusted on Windows.


Signing Applications in Other Languages

C# with Visual Studio

For developers working with C# and Visual Studio, the process is similar but often integrated into the IDE.

  1. Obtain a Code Signing Certificate: Follow the same procedure as above.

  2. Add the Certificate to Your Project:

    • In Visual Studio, right-click your project and select Properties.
    • Go to the Signing tab.
    • Check Sign the assembly.
    • Browse and select your certificate (.pfx file).
  3. Build Your Project:

    • Visual Studio will automatically sign the output executable using the provided certificate.
  4. Verify the Signature:

    • Use signtool verify from the Developer Command Prompt to ensure the signature is correct.

Other Languages

The code signing process remains consistent across various languages. Here’s a general approach:

  1. Compile Your Application: Ensure you have the final executable.
  2. Sign Using Signtool: Run the appropriate signtool command as demonstrated above.
  3. Verify the Signature: Confirm the process using the verification command.

This workflow can be applied to languages like C++, Delphi, or even Java (if you’re packaging an application as an executable wrapper).


Conclusion

Code signing is a critical step in ensuring your application is trusted by Windows users. While obtaining a certificate involves an upfront cost, it significantly improves user experience and reduces the friction of installation warnings. Whether you're developing in Rust, C#, or any other language, following these steps with signtool will help you secure and distribute your applications confidently.

Happy coding!