|
|
||
|---|---|---|
| .gitignore | ||
| CLAUDE.md | ||
| generate.ps1 | ||
| install-cert.ps1 | ||
| LICENSE | ||
| openssl-codesign.cnf | ||
| README.md | ||
| sign.ps1 | ||
| verify.ps1 | ||
Code Signing Certificate
PowerShell scripts to create, install, and use a self-signed code signing certificate for Windows.
Overview
Code signing attaches a cryptographic signature to your application so that:
- Windows can verify the file has not been tampered with since it was signed
- Users see your name instead of "Unknown Publisher" in UAC prompts
- Antivirus tools are less likely to flag your app as suspicious
This project uses OpenSSL to generate a private key and self-signed certificate, then osslsigncode or signtool (Windows SDK) to sign your binaries.
Note: Self-signed certificates will still trigger Windows SmartScreen warnings for end users unless the certificate is installed in their Trusted Publishers store. For public distribution without warnings, use a certificate from a trusted CA (DigiCert, Sectigo, etc.).
Requirements
Install the following tools before running any scripts:
| Tool | Required | Install (Windows) |
|---|---|---|
| OpenSSL | Yes | winget install FireDaemon.OpenSSL or winget install ShiningLight.OpenSSL.Light |
| signtool | Recommended | Included with Windows SDK |
| osslsigncode | Alternative to signtool | winget install osslsigncode |
Run scripts from PowerShell (5.1 or 7+). Right-click the Start menu → "Windows PowerShell" or "Terminal".
Project Structure
CodeSigningCert/
├── openssl-codesign.cnf # OpenSSL config — edit CN/O/C before first run
├── generate.ps1 # Step 1: generate key, certificate, and PFX
├── install-cert.ps1 # Step 2: install certificate into Windows trust stores
├── sign.ps1 # Step 3: sign an executable (GUI file picker)
├── verify.ps1 # Step 4: verify a signed executable (GUI file picker)
├── .gitignore # Prevents private keys from being committed
├── CLAUDE.md # AI assistant context for this project
└── certs\ # Created by generate.ps1 (gitignored)
├── codesign.key # Private key — keep secret
├── codesign.crt # Certificate — public
└── codesign.pfx # PKCS#12 bundle used for signing
Setup
1. Configure your certificate details
Open openssl-codesign.cnf and update the [ req_distinguished_name ] section:
[ req_distinguished_name ]
CN = My Code Signing Certificate # Your name or app name
O = My Organization # Your company or personal brand
C = US # Two-letter country code
2. Generate the certificate
.\generate.ps1
This creates the certs\ directory and produces three files:
certs\codesign.key— your private key (never share or commit this)certs\codesign.crt— your public certificatecerts\codesign.pfx— a PKCS#12 bundle used by signing tools
You will be prompted to set a PFX export password during generation. Save it in a password manager.
Optional: Override the certificate validity period (default is 10 years):
.\generate.ps1 -Days 365
Signing a File
# Pass the file directly
.\sign.ps1 -File MyApp.exe
# Or run without arguments — a file picker dialog will open
.\sign.ps1
The signed output is saved as <filename>-signed.exe in the same folder as the original.
Supply the PFX password directly (avoids the interactive prompt):
.\sign.ps1 -File MyApp.exe -PfxPass "yourpassword"
Use a custom timestamp server:
.\sign.ps1 -File MyApp.exe -TimestampUrl "http://timestamp.sectigo.com"
The script automatically uses signtool if available, falling back to osslsigncode.
Verifying a Signature
# Pass the file directly
.\verify.ps1 -File MyApp.exe
# Or run without arguments — a file picker dialog will open
.\verify.ps1
A message box shows whether the signature is valid. The script tries signtool, then osslsigncode, and falls back to PowerShell's built-in Get-AuthenticodeSignature.
Trusting the Certificate Locally (Windows)
To suppress UAC/SmartScreen warnings on your own machine, use the included script to install the certificate into the Windows trust stores:
# Install for all users (requires Administrator)
.\install-cert.ps1
# Install for current user only (no Administrator needed)
.\install-cert.ps1 -Scope CurrentUser
# Remove the certificate later
.\install-cert.ps1 -Uninstall
This installs the certificate into both Trusted Root Certification Authorities and Trusted Publishers, which is required for Windows to fully trust signed executables.
Manual alternative: Double-click certs/codesign.pfx, choose Local Machine, and place it in the Trusted Publishers store.
Security Reminders
- The
certs/directory is gitignored. Never commit.key,.pfx, or.p12files. - Always use a timestamp server when signing (
sign.ps1does this automatically). This ensures signatures remain valid even after the certificate expires. - Store your PFX password in a password manager, not in shell scripts or environment files.
Common Timestamp Servers
| Provider | URL |
|---|---|
| DigiCert | http://timestamp.digicert.com |
| Sectigo | http://timestamp.sectigo.com |
| GlobalSign | http://timestamp.globalsign.com/scripts/timstamp.dll |
The default used by sign.ps1 is DigiCert.