| Crates.io | yubikey-signer |
| lib.rs | yubikey-signer |
| version | 0.7.1 |
| created_at | 2025-08-08 16:50:02.537477+00 |
| updated_at | 2026-01-05 20:32:05.435728+00 |
| description | YubiKey code signing utility |
| homepage | https://github.com/dgehri/yubikey-signer |
| repository | https://github.com/dgehri/yubikey-signer |
| max_upload_size | |
| id | 1787039 |
| size | 1,290,902 |
Code signing utility for PE executables using YubiKey PIV certificates with OpenSSL-based Authenticode signatures. Supports local signing with a directly connected YubiKey or remote signing via an HTTP proxy server.
sudo systemctl start pcscd)yubikey-proxy serverSign a file in-place (replaces the original):
yubikey-signer sign myapp.exe
Save signed file to a different location:
yubikey-signer sign myapp.exe -o myapp-signed.exe
Sign using a remote YubiKey proxy server:
yubikey-signer sign myapp.exe -o signed.exe --remote http://192.168.1.100:18443
With authentication token:
export YUBIKEY_PROXY_TOKEN="your-secret-token"
yubikey-signer sign myapp.exe -o signed.exe --remote http://proxy:18443
With custom HTTP headers (for reverse proxies like Cloudflare Access):
yubikey-signer sign myapp.exe -o signed.exe \
--remote https://sign.example.com \
--header "CF-Access-Client-Id: your-client-id.access" \
--header "CF-Access-Client-Secret: your-client-secret"
With timestamp server:
yubikey-signer sign myapp.exe --timestamp http://timestamp.digicert.com
Without timestamping (not recommended for production):
yubikey-signer sign myapp.exe --timestamp ""
Specify a specific PIV slot:
yubikey-signer sign myapp.exe --slot 0x9c
Find suitable certificates on your YubiKey:
yubikey-signer discover
Get detailed certificate information:
yubikey-signer discover --detailed
View current configuration:
yubikey-signer config show
Initialize default configuration:
yubikey-signer config init
Set configuration values:
yubikey-signer config set default_piv_slot 0x9c
Local signing - Set YubiKey PIN via environment variable:
export YUBICO_PIN=123456 # Linux/macOS
$env:YUBICO_PIN = "123456" # Windows PowerShell
Remote signing - Set proxy authentication token:
export YUBIKEY_PROXY_TOKEN="your-secret-token" # Linux/macOS
$env:YUBIKEY_PROXY_TOKEN = "your-secret-token" # Windows PowerShell
Download from GitHub Releases:
yubikey-signer-x86_64-pc-windows-msvc.exeyubikey-signer-x86_64-unknown-linux-gnuyubikey-signer-x86_64-apple-darwinyubikey-signer-aarch64-apple-darwin# Run the automated setup script (PowerShell as Administrator)
.\setup-windows-build.ps1
# Or use the batch file
.\setup-windows-build.bat
# Then build normally
cargo build --release
The setup script will automatically:
VCPKG_ROOT)If you already have vcpkg:
# Install OpenSSL via your existing vcpkg
vcpkg install openssl:x64-windows
# Set environment variable (if not already set)
set VCPKG_ROOT=C:\your\vcpkg\path
# Build normally
cargo build --release
# Uses system OpenSSL or vendored if system not available
cargo build --release
# Force vendored OpenSSL (requires dependencies)
cargo build --release --features vendored-openssl
Windows PowerShell (optional):
Get-AuthenticodeSignature myapp-signed.exe
The CLI provides four main commands:
sign - Sign PE executables with YubiKey certificates (local or remote)proxy - Run a signing proxy server for remote signingdiscover - Find and analyze certificates on your YubiKeyconfig - Manage application configurationyubikey-signer sign [OPTIONS] <FILE>
Arguments:
<FILE> PE executable file to sign
Options:
-o, --output <FILE> Output file (default: sign in-place)
-s, --slot <SLOT> PIV slot (hex: 0x9c, 9c, or decimal: 156)
-t, --timestamp [<URL>] Timestamp server URL (default: http://ts.ssl.com)
-r, --remote <URL> Remote signing proxy URL
--header <HEADER> Custom HTTP header (format: "Name: Value"), repeatable
--dry-run Preview signing without making changes
-v, --verbose Enable verbose output
-h, --help Print help
Start a signing proxy server (requires YubiKey connected to the host):
yubikey-signer proxy [OPTIONS]
Options:
-b, --bind <ADDR> Bind address (default: 127.0.0.1:18443)
-v, --verbose Enable verbose output
-h, --help Print help
Environment:
YUBICO_PIN YubiKey PIN for signing operations
YUBIKEY_PROXY_TOKEN Required authentication token for clients
yubikey-signer discover [OPTIONS]
Options:
--detailed Show detailed certificate information
-v, --verbose Enable verbose output
-h, --help Print help
yubikey-signer config <SUBCOMMAND>
Subcommands:
show Display current configuration
init Create default configuration file
set Set configuration value
export Export configuration
import Import configuration
help Print help
Common YubiKey PIV slots for code signing:
0x9a (154): Authentication - Default slot for signing0x9c (156): Digital Signature - Primary slot for code signing0x9d (157): Key Management - Alternative signing slot0x9e (158): Card Authentication - Alternative signing slotRemote signing allows code signing from machines without a directly connected YubiKey. The YubiKey remains connected to a secure server running the proxy.
┌─────────────────┐ ┌─────────────────┐ ┌─────────────┐
│ Build Machine │ HTTPS │ Proxy Server │ USB │ YubiKey │
│ │ ──────► │ (yubikey-proxy)│ ──────► │ │
│ yubikey-signer │ │ │ │ PIV Cert │
│ --remote URL │ ◄────── │ Port 18443 │ ◄────── │ Private Key│
└─────────────────┘ └─────────────────┘ └─────────────┘
Connect YubiKey to the server
Set environment variables:
export YUBICO_PIN="your-yubikey-pin"
export YUBIKEY_PROXY_TOKEN="$(openssl rand -base64 36)"
Start the proxy:
yubikey-signer proxy --bind 0.0.0.0:18443
For production, place behind a TLS-terminating reverse proxy (nginx, Caddy, Cloudflare Tunnel)
The proxy exposes these endpoints:
| Method | Path | Description |
|---|---|---|
| POST | /api/v1/status |
Server and YubiKey status |
| POST | /api/v1/certificate |
Get certificate from PIV slot |
| POST | /api/v1/sign |
Sign a hash digest |
All endpoints require the Authorization: Bearer <token> header.
CI builds and releases are tested for:
x86_64-pc-windows-msvcx86_64-unknown-linux-gnux86_64-apple-darwinaarch64-apple-darwinaarch64-unknown-linux-musl (proxy binary with direct USB support for embedded Linux)Automated dependency scanning and license compliance is handled by cargo-deny, configured via deny.toml.
cargo install cargo-deny
# Complete dependency compliance check (licenses, advisories, bans, sources)
cargo deny check
# Individual checks
cargo deny check licenses
cargo deny check advisories
cargo deny check bans
cargo deny check sources
Ignored advisories are documented with justification and expiry inside deny.toml. Remove or update entries once upstream crates patch vulnerabilities.
CI GitHub Actions workflow runs these checks on pushes, pull requests, and a daily schedule; any new unignored vulnerability or disallowed license will fail the workflow.
This project is licensed under the Apache License, Version 2.0. See the LICENSE file for details.
This software includes third-party components under their respective licenses:
--use-openssl option): Apache License 2.0
LICENSE-OpenSSLTHIRD-PARTY-NOTICES.mdcargo license for a complete listSee THIRD-PARTY-NOTICES.md for complete attribution and license information for all third-party components.