
Security News
The Hidden Blast Radius of the Axios Compromise
The Axios compromise shows how time-dependent dependency resolution makes exposure harder to detect and contain.
@certchip/signer
Advanced tools
Cross-platform code and document signing CLI tool with SSH key authentication.
Note: This program module can be used in environments where Certchip Signer Server is deployed.
-cert-dist)-letsencrypt)-cert, -privkey, -pubkey, -csr)# Global installation (recommended)
npm install -g @certchip/signer
# Or local installation
npm install @certchip/signer
# Login with SSH key authentication
signercli -login https://signer.example.com username
# Sign a file (two equivalent forms)
signercli myapp.exe # Implicit form
signercli -sign myapp.exe # Explicit form
# Verify signature
signercli -verify myapp.exe
# Logout
signercli -logout
# Login (certificate is installed to Windows certificate store)
signer -login https://signer.example.com username
# Sign directly with signer (two equivalent forms, same options as signercli)
signer myapp.exe # Implicit form (default: hash-only mode)
signer -sign myapp.exe # Explicit form
signer myapp.exe -o myapp_signed.exe # Specify output file
signer myapp.exe -file-upload -save-signed # Upload file, save with _signed suffix
# Or use Windows signtool.exe (after login)
signtool sign /n "Your Certificate CN" /fd sha256 /tr http://timestamp.digicert.com /td sha256 myapp.exe
# Logout (removes certificate from store)
signer -logout
# signercli (Cross-platform)
npx signercli -login https://signer.example.com username
npx signercli myapp.exe
# signer (Windows only)
npx signer -login https://signer.example.com username
npx signer myapp.exe
This package provides two CLI tools with different capabilities:
| signercli | signer | |
|---|---|---|
| Purpose | Full-featured signing and certificate management | Windows signtool.exe integration + direct signing |
| Platform | Windows, Linux, macOS | Windows only |
| How it works | Signs files directly via server API | Registers certificates in Windows store for signtool.exe integration |
| Best for | CI/CD, automation, cross-platform, certificate management | Windows developers, signtool.exe, Visual Studio integration |
| Feature | signercli | signer |
|---|---|---|
| Platform Support | ||
| Windows | ✅ | ✅ |
| Linux | ✅ | ❌ |
| macOS | ✅ | ❌ |
| ARM64 support | ✅ | ❌ |
| Authentication | ||
| SSH key (Ed25519, ECDSA, RSA) | ✅ | ✅ |
| Password authentication | ✅ | ✅ |
| API key (no login required) | ✅ | ❌ |
| Profile-based configuration | ✅ | ✅ |
| File Signing | ||
| PE executables (.exe, .dll, .sys, .ocx) | ✅ | ✅ |
| Installers (.msi, .msp, .cab) | ✅ | ✅ |
| PDF documents | ✅ | ✅ |
| Scripts (.ps1, .vbs) | ✅ | ✅ |
| Source code (JS, Python, Go, Rust, etc.) | ✅ | ✅ |
| JAR files | ✅ | ✅ |
| Hash-only signing (default) | ✅ | ✅ |
| File upload signing | ✅ | ✅ |
| PDF Signature Options | ||
| Watermark style | ✅ | ✅ |
| Box style | ✅ | ✅ |
| Barcode style | ✅ | ✅ |
| QR code style | ✅ | ✅ |
| Position/opacity control | ✅ | ✅ |
| Certificate Management | ||
| List certificates | ✅ | ✅ |
| Get/Set certificate ID | ✅ | ✅ |
| Get certificate PEM | ✅ | ✅ |
| Set private key password | ✅ | ✅ |
| Upload certificates | ✅ | ❌ |
| Download certificates (PEM/DER/PFX) | ✅ | ❌ |
| Delete certificates | ✅ | ❌ |
| Update certificate metadata | ✅ | ❌ |
| Private Key Management | ||
| List private keys | ✅ | ❌ |
| Upload private keys | ✅ | ❌ |
| Download private keys | ✅ | ❌ |
| Delete private keys | ✅ | ❌ |
| Link/Unlink to certificates | ✅ | ❌ |
| CSR & Public Key | ||
| Generate CSR | ✅ | ❌ |
| Public key management | ✅ | ❌ |
| Certificate Distribution | ||
| Let's Encrypt SSL certificates | ✅ | ❌ |
| Let's Encrypt direct management | ✅ | ❌ |
| Device certificates | ✅ | ❌ |
| Signing certificates | ✅ | ❌ |
| Auto-renewal check | ✅ | ❌ |
| Multiple download formats | ✅ | ❌ |
| Windows Integration | ||
| signtool.exe integration | ❌ | ✅ |
| Windows certificate store | ❌ | ✅ |
| KSP provider registration | ❌ | ✅ |
| Key container management | ❌ | ✅ |
| Output & Automation | ||
| Classic output | ✅ | ✅ |
| JSON output | ✅ | ❌ |
| Table output | ✅ | ❌ |
| CSV output | ✅ | ❌ |
| Log level control | ✅ | ✅ |
| Scenario | Recommended Tool |
|---|---|
| CI/CD pipeline (any platform) | signercli - Cross-platform, JSON output, API key auth |
| Linux/macOS development | signercli - Only option for non-Windows |
| Simple file signing | signercli or signer - Both work equally |
| Windows signtool.exe integration | signer - Registers cert to Windows store |
| Visual Studio post-build signing | signer - signtool.exe compatible |
| Windows certificate store integration | signer - KSP provider support |
| Certificate upload/download/delete | signercli - -cert with API key |
| Let's Encrypt certificate distribution | signercli - -cert-dist command |
| Let's Encrypt direct management | signercli - -letsencrypt command |
| Private key management | signercli - -privkey command |
| CSR generation | signercli - -csr command |
| Automation without SSH keys | signercli - API key authentication |
| Parsing output in scripts | signercli - -format json option |
The main CLI tool for code and document signing. Signs files directly by communicating with the signing server. Works on all platforms without any additional setup.
# Auto-detect authentication (SSH key if exists, otherwise password prompt)
signercli -login <url> [username]
# SSH Key Authentication (explicit)
signercli -login <url> -key ~/.ssh/id_ed25519
signercli -login <url> username -key ~/.ssh/id_rsa
# Password Authentication
signercli -login <url> -user <userid> # Password prompted interactively
signercli -login <url> -user <userid> -pw <password> # Password on command line
# Login Options
-profile <name> Use specific config profile
-expires <time> Token expiration (e.g., 24h, 7d, 1w)
-cert-id <id> Pre-specify certificate ID
-cert-serial <sn> Pre-specify certificate serial number
-include-chain Include certificate chain in token
# Logout
signercli -logout [url]
# Basic signing (default: hash-only mode)
signercli <file> # Implicit form
signercli -sign <file> # Explicit form (same result)
# Signing options
signercli <file> -o <output> # Specify output file
signercli -sign <file> -o <output> # Explicit form
signercli <file> -save-signed # Save with _signed suffix (preserve original)
signercli <file> -hash-only # Hash-based signing (default)
signercli <file> -file-upload # Upload entire file to server
signercli <file> -hash-algorithm <alg> # sha256, sha384, sha512
signercli <file> -timestamp-url <url> # Timestamp server URL
signercli <file> -profile <name> # Use config profile
Note: Both
signercli <file>(implicit) andsignercli -sign <file>(explicit) forms are equivalent. The explicit form makes intent clearer in scripts and automation.
Note: Hash-only signing is the default mode. Only the file hash is sent to the server, not the entire file.
signercli -verify <file>
signercli -verify <file> -signature-id <id> # Verify specific signature
signercli -verify <file> -profile <name>
# List available certificates
signercli -codesign-list
# Get/Set certificate ID
signercli -codesign-id # Show current certificate ID
signercli -codesign-id <id> # Set certificate ID
# Get certificate PEM
signercli -codesign-cert # Fetch current certificate
signercli -codesign-cert -id <id> # Fetch specific certificate
signercli -codesign-cert -o cert.pem # Save to file
# Set private key password (for password-protected keys on server)
signercli -codesign-set <password>
Alternative: -cert commands (compatible with signer.exe)
# List certificates (with purpose filter)
signercli -cert list # List all certificates with private keys (default)
signercli -cert list any # List all certificates (including without private keys)
signercli -cert list codesign # List code signing certificates
signercli -cert list docsign # List document signing certificates
signercli -cert list serverauth # List server authentication (SSL/TLS) certificates
signercli -cert list clientauth # List client authentication certificates
signercli -cert list ca # List CA certificates
signercli -cert list timestamp # List timestamping certificates
signercli -cert list ocsp # List OCSP signing certificates
signercli -cert list encrypt # List encryption certificates
signercli -cert list verify # List verification certificates
# Get/Set certificate ID
signercli -cert -id # Show current configuration
signercli -cert -id <cert_id> # Set certificate ID
signercli -cert -id <cert_id> <label> # Set with label
# Get certificate PEM
signercli -cert -pem
# Set private key password
signercli -cert -password <password>
Note: The
-certcommands use the same API endpoints assigner.exe, ensuring full compatibility between both tools.
The configuration file allows you to store connection settings, authentication credentials, and signing options in reusable profiles. This eliminates the need to specify the same options repeatedly on the command line.
Detailed guide: See docs/CONFIG-FILE-GUIDE.md for complete configuration options and examples.
Why Use Configuration Profiles:
Understanding the Default Profile:
The [default] profile is special - it serves as the base configuration for all operations:
-profile option is specified, SignerCLI automatically uses [default][production] or [staging]) inherit all settings from [default][default]This inheritance model means you should:
[default]┌─────────────────────────────────────────────────────┐
│ [default] │
│ host = https://signer.example.com:7443 │
│ api_key = cdk_xxx... │
│ hash_algorithm = sha256 │
├─────────────────────────────────────────────────────┤
│ [production] │ [staging] │
│ cert_id = prod-001 │ host = https://stg:7443│
│ (inherits host, │ cert_id = stg-001 │
│ api_key, hash_alg) │ (inherits api_key, │
│ │ hash_alg) │
└───────────────────────────┴─────────────────────────┘
Config File Location:
| OS | Path |
|---|---|
| Linux/macOS | ~/.signer/config |
| Windows | %USERPROFILE%\.signer\config |
Basic Commands:
# View configuration
signercli -config # Show entire config file
signercli -config list # List all profiles
signercli -config show <name> # Show specific profile details
# Create/Update profile (profile name defaults to 'default' if omitted)
signercli -config set [name] [options]
# Remove specific settings from profile
signercli -config unset [name] <options>
# Delete entire profile
signercli -config delete <name>
Removing Settings (-config unset):
# Remove api_key from default profile
signercli -config unset -api-key
# Remove multiple settings
signercli -config unset -api-key -host
# Remove from named profile
signercli -config unset production -cert-id
API Key Authentication (No Login Required):
Store an API key in a profile to use -cert, -privkey, -pubkey, -csr, -cert-dist commands without login.
# Set API key in default profile (profile name omitted = 'default')
signercli -config set \
-host https://signer.example.com:7443 \
-api-key cdk_e2f369e7c85bfa7835d375f6b088f15dac2c2d8ebeb0815c392a6d6b34ee916f
# Same as above (explicit 'default')
signercli -config set default \
-host https://signer.example.com:7443 \
-api-key cdk_e2f369e7c85bfa7835d375f6b088f15dac2c2d8ebeb0815c392a6d6b34ee916f
# Use commands without login (API key auto-applied)
signercli -cert list
signercli -cert get <id>
signercli -cert upload cert.pem -name "My Cert"
signercli -cert-dist list
Profile Inheritance Example:
# Set common settings in default profile (profile name optional)
signercli -config set \
-host https://signer.example.com:7443 \
-api-key cdk_common_api_key \
-hash-algorithm sha256
# Create production profile (inherits host, api_key, hash-algorithm)
signercli -config set production -cert-id prod-cert-001
# Create staging profile (overrides host, inherits others)
signercli -config set staging \
-host https://staging.example.com:7443 \
-cert-id staging-cert-001
# Usage
signercli -cert list # Uses default profile
signercli -cert list -profile production # Uses production profile
signercli -cert list -profile staging # Uses staging profile
Inheritance Display:
$ signercli -config show production
Profile: [production]
----------------------------------------
host = https://signer.example.com:7443 (default)
api_key = cdk_common_api_key (default)
cert_id = prod-cert-001
hash_algorithm = sha256 (default)
The
(default)marker indicates the value is inherited from the[default]profile.
Authentication Priority:
-api-key, -host) - Highest priority-profile <name>)# Command-line args override profile settings
signercli -cert list -profile production -host https://other:7443
# → Uses other:7443 (ignores production's host)
Profile Options:
| Option | Description |
|---|---|
-host <url> | Server URL |
-ssh-key-path <path> | SSH private key path |
-username <name> | SSH username |
-user <id> | User ID for password auth |
-api-key <key> | API key (bypasses login) |
-cert-id <id> | Default certificate ID |
-cert-serial <sn> | Certificate serial number |
-expires <time> | Token expiration (24h, 7d, 1w) |
-include-chain | Include certificate chain |
-timestamp-url <url> | Timestamp server URL |
-hash-algorithm <alg> | Hash algorithm (sha256, sha384, sha512) |
-output-format <type> | Output format (classic, json, table, csv) |
Document Signing Options:
| Option | Description |
|---|---|
-doc-style <style> | watermark, box, barcode, qrcode |
-doc-position <pos> | bottom-right, bottom-left, top-right, top-left, center |
-doc-sig-position <pos> | left, center, right (for barcode/qrcode) |
-doc-font-size <size> | Signature font size |
-doc-opacity <value> | Opacity (0.0-1.0 or 0-100) |
Config File Example (~/.signer/config):
[default]
host=https://signer.example.com:7443
api_key=cdk_e2f369e7c85bfa7835d375f6b088f15dac2c2d8ebeb0815c392a6d6b34ee916f
hash_algorithm=sha256
output_format=classic
[production]
cert_id=prod-codesign-001
timestamp_url=http://timestamp.digicert.com
include_chain=true
[ci-automation]
api_key=cdk_ci_specific_api_key
output_format=json
cert_id=automation-cert-001
Security Notes:
chmod 600 ~/.signer/config (Linux/macOS)# Install DLLs to System32 (auto-requests UAC elevation)
signercli -install
# Remove DLLs from System32
signercli -uninstall
signercli -help
signercli -version
# Log levels (append to any command for debugging)
signercli <file> LOG_DBG # Debug output
signercli <file> LOG_INF # Info output
# Available: LOG_NON, LOG_ERR, LOG_WRN, LOG_DBG, LOG_INF
Version Output:
The -version command displays comprehensive version information:
# signercli -version
Certchip Signer CLI v0.1.28
Cross-platform code and document signing tool
Copyright (c) 2026 Certchip. All rights reserved.
DLL Versions (Local):
otpkey.dll: 0.1.28.0
Certchip.dll: 0.1.28.0
DLL Versions (System32):
otpkey.dll: 0.1.28.0
Certchip.dll: 0.1.28.0
| Information | Description |
|---|---|
| CLI Version | signercli/signer executable version |
| Local DLL | DLL versions in the same directory as the executable |
| System32 DLL | DLL versions installed in Windows System32 folder |
Note: DLL version information is Windows-only. On Linux/macOS, only the CLI version is displayed.
Both signercli and signer support structured output formats for scripting and automation.
# JSON format (default for scripting)
signercli -verify myapp.exe -format json
signercli -config list -format json
signercli -logout -format json
# Table format (aligned columns)
signercli -verify myapp.exe -format table
# CSV format (spreadsheet-friendly)
signercli -config list -format csv
# Classic format (default - human-readable)
signercli -verify myapp.exe
Format Options:
| Format | Description | Best for |
|---|---|---|
classic | Human-readable output (default) | Interactive use |
json | JSON structured output | CI/CD, scripting, automation |
table | Aligned table format | Terminal display |
csv | Comma-separated values | Spreadsheets, data processing |
Example: JSON output from verify command
$ signercli -verify myapp.exe -format json
{
"command": "verify",
"status": "valid",
"file": "myapp.exe",
"method": "AUTHENTICODE",
"signer": "Example Company",
"serialNumber": "0123456789abcdef",
"timestamp": "2025-01-15 10:30:00",
"success": true
}
Example: JSON output from config list
$ signercli -config list -format json
{
"command": "config-list",
"count": 3,
"profiles": ["default", "production", "staging"],
"success": true
}
Example: JSON output from login
$ signercli -login https://signer.example.com admin -pw secret -format json
{
"command": "login",
"status": "success",
"username": "admin",
"expiresIn": 86400,
"certificate": {
"cn": "Example Company Code Signing"
},
"success": true
}
Note: Interactive authentication (password prompt, SSH key selection) is not available with structured output formats. Use
-userand-pwoptions or-keyoption for non-interactive login.
Windows-specific tool that integrates with the Windows cryptographic system via KSP (Key Storage Provider). It can both sign files directly (like signercli) and register certificates in the Windows certificate store for use with signtool.exe.
Two signing methods:
signer <file> or signer -sign <file> (same as signercli)# Authentication (fetches certificate to Windows store)
signer -login <url> [username] # Login and register certificate
signer -logout # Logout and remove certificate
# File Signing (direct - same options as signercli)
signer <file> [options] # Sign a file (implicit form)
signer -sign <file> [options] # Sign a file (explicit form)
-o <path> # Output file path
-hash-only # Hash-based signing (default)
-file-upload # Upload entire file to server
-save-signed # Save with _signed suffix
-profile <name> # Use specific signing profile
# Certificate Management
signer -cert -list # List available certificates
signer -cert -list codesign # Filter by purpose
signer -cert -id # Show current certificate configuration
signer -cert -id <cert_id> # Set certificate ID
signer -cert -pem # Get certificate PEM
signer -cert -password <password> # Set private key password
# KSP Provider Management
signer -register # Register Certchip KSP provider
signer -unregister # Unregister KSP provider
signer -enum # List all crypto providers
signer -container # List key containers
# DLL Installation (auto-requests UAC elevation)
signer -install # Install DLLs to System32
signer -uninstall # Remove DLLs from System32
# Version & Help
signer -version # Show version and DLL info
signer -help # Show usage help
# After login, use standard Windows signing tools (signtool integration)
signtool sign /n "Certificate Name" /fd sha256 myapp.exe
signtool sign /sha1 <thumbprint> /fd sha256 /tr http://timestamp.digicert.com myapp.exe
Examples:
# Direct signing with output path (two equivalent forms)
signer myapp.exe -o myapp_signed.exe
signer -sign myapp.exe -o myapp_signed.exe
# Upload entire file for signing
signer myapp.exe -file-upload -o myapp_signed.exe
# Hash-only signing with _signed suffix
signer myapp.exe -save-signed
signer -sign myapp.exe -save-signed
Version Output:
# signer -version
Certchip Signer v0.1.28
Windows Key Storage Provider and Code Signing Tool
Copyright (c) 2026 Certchip. All rights reserved.
DLL Versions (Local):
otpkey.dll: 0.1.28.0
Certchip.dll: 0.1.28.0
DLL Versions (System32):
otpkey.dll: 0.1.28.0
Certchip.dll: 0.1.28.0
The version output helps diagnose DLL version mismatches between local and system-wide installations.
Download and manage certificates from a remote server. Supports various certificate types including SSL/TLS, device, and signing certificates.
Supported Certificate Types:
# Check certificate status
signercli -cert-dist status <domain> -api-key <key> -host <url>
# Check if renewal is needed
signercli -cert-dist check <domain> -api-key <key> -host <url>
# Download certificate
signercli -cert-dist download <domain> -api-key <key> -host <url> [-format <type>] [-o <dir>]
# Trigger certificate renewal
signercli -cert-dist renew <domain> -api-key <key> -host <url> [-force] [-wait|-no-wait]
# List available domains
signercli -cert-dist list -api-key <key> -host <url>
# Full sync (check + renew + download)
signercli -cert-dist sync <domain> -api-key <key> -host <url> [-reload-cmd <cmd>]
# Help
signercli -cert-dist help
API keys support two permission modes:
| Mode | Description |
|---|---|
explicit | Use only the permissions explicitly assigned to the API key |
inherited | Inherit permissions from the linked user account's role and groups |
Explicit Mode:
Inherited Mode:
| Permission | Description | cert-dist | cert-api | letsencrypt |
|---|---|---|---|---|
read | View certificate info | ✅ | ✅ | ✅ |
renew | Renew certificates | ✅ | - | - |
download | Download certificates | ✅ | ✅ | ✅ |
upload | Upload certificates/keys | - | ✅ | - |
delete | Delete certificates/keys | - | ✅ | - |
edit | Edit metadata | - | ✅ | - |
csr | Generate CSR | - | ✅ | - |
hsm | HSM operations (protect/unprotect) | - | ✅ | - |
letsencrypt | Let's Encrypt SSL certificate management | - | - | ✅ |
all | All permissions | ✅ | ✅ | ✅ |
Link a user account to an API key for:
inherited mode to automatically apply user permissionsFormat Options by Command:
| Command | -format json | File Formats |
|---|---|---|
status | ✅ JSON output | - |
check | ✅ JSON output | - |
list | ✅ JSON output | - |
renew | ✅ JSON output | - |
download | ✅ JSON output | nginx, pem, letsencrypt, json (file) |
sync | ✅ JSON output | nginx, pem, letsencrypt |
Download File Formats:
| Format | Description | Generated Files |
|---|---|---|
nginx | Nginx format (default) | <domain>.crt, <domain>.key |
pem | Standard PEM format | <domain>.fullchain.pem, <domain>.privkey.pem |
letsencrypt | Let's Encrypt style | <domain>/cert.pem, <domain>/chain.pem, <domain>/fullchain.pem, <domain>/privkey.pem |
json | JSON format | <domain>.json |
Note: Wildcard domains (e.g.,
*.example.com) are automatically sanitized for file/folder names. The*and other invalid filename characters are replaced with_. For example,*.example.combecomes_.example.comin file paths.
Examples:
# Download in Nginx format (default)
signercli -cert-dist download example.com -api-key cdk_xxx -host https://signer.example.com:7443
# Download in Let's Encrypt style
signercli -cert-dist download example.com -api-key cdk_xxx -host https://signer.example.com:7443 \
-format letsencrypt -o /etc/letsencrypt/live
# Automation: renew if needed, download, and reload Nginx
signercli -cert-dist sync example.com -api-key cdk_xxx -host https://signer.example.com:7443 \
-o /etc/nginx/ssl -reload-cmd "systemctl reload nginx"
# Get status in JSON format (for scripting)
signercli -cert-dist status example.com -api-key cdk_xxx -host https://signer.example.com:7443 -format json
Exit Codes:
0: Success (for check command: no renewal needed)1: Error2: Renewal needed (check command only)Detailed usage: See cert-dist-guide.md
General certificate and key management commands. Uses the same API key as cert-dist.
Three Command Systems:
| Commands | Purpose | API Endpoint |
|---|---|---|
-cert-dist | Let's Encrypt certificate distribution/renewal | /api/cert-distribution |
-cert, -privkey, -pubkey, -csr | General certificate/key management | /api/cert-api |
-letsencrypt | Let's Encrypt SSL certificate direct management | /api/cert-api/letsencrypt |
API keys allow direct API access without SSH key-based login.
What is an API Key?
cdk_ prefix + 64-char hex)API Key Format:
cdk_e2f369e7c85bfa7835d375f6b088f15dac2c2d8ebeb0815c392a6d6b34ee916f
Usage Methods:
# Method 1: Specify directly on command line
signercli -cert list -api-key cdk_xxx -host https://server:7443
# Method 2: Store in profile (recommended)
signercli -config set default -host https://server:7443 -api-key cdk_xxx
signercli -cert list # api-key and host auto-applied
# Method 3: Use named profile
signercli -config set production -host https://prod:7443 -api-key cdk_prod_key
signercli -cert list -profile production
Supported Commands:
| Command | Description |
|---|---|
-cert | Certificate management (list, upload, download, delete) |
-cert-dist | Let's Encrypt certificate distribution/renewal |
-letsencrypt | Let's Encrypt SSL certificate direct management |
-privkey | Private key management |
-pubkey | Public key management |
-csr | Certificate Signing Request generation |
Login Authentication vs API Key Authentication:
| Aspect | Login Authentication | API Key Authentication |
|---|---|---|
| Method | SSH key challenge-response | Direct API key transmission |
| Token Expiry | Yes (default 24h) | Depends on server config |
| Commands | All commands after -login | -cert, -cert-dist, etc. only |
| Best For | Interactive use, code signing | Automation, CI/CD, scripts |
Security Notes:
chmod 600 ~/.signer/config# List certificates
signercli -cert list -api-key <key> [-host <url>]
# Get certificate details
signercli -cert get <id> -api-key <key>
# Upload certificate (default: DB storage)
signercli -cert upload <file> -name "Certificate Name" -api-key <key>
# Upload certificate to Software HSM (no PIN required)
signercli -cert upload <file> -name "My Cert" -storage SW_HSM -api-key <key>
# Upload certificate to Hardware HSM (slot and PIN required)
signercli -cert upload <file> -name "My Cert" -storage HW_HSM -hsm-slot 0 -hsm-pin <pin> -api-key <key>
# Download certificate (PEM/DER)
signercli -cert download <id> -format pem -o <dir> -api-key <key>
# Download certificate (PFX)
signercli -cert download-pfx <id> -password <pwd> -o <dir> -api-key <key>
# Update certificate metadata
signercli -cert update <id> -name "New Name" -desc "Description" -api-key <key>
# Delete certificate
signercli -cert delete <id> -api-key <key>
# Delete certificate with related private key
signercli -cert delete <id> -delete-related -api-key <key>
# Delete HSM certificate (PIN required)
signercli -cert delete <id> -hsm-pin <pin> -api-key <key>
Storage Types:
| Type | Description | Requirements |
|---|---|---|
DB | Database storage (default) | None |
SW_HSM | Software HSM (encrypted storage) | None |
HW_HSM | Hardware HSM (PKCS#11 device) | -hsm-slot, -hsm-pin |
Using Profile with API Key:
You can store the API key in a profile to avoid specifying it on every command:
# Configure profile with API key (one-time setup)
signercli -config set default -host https://server:7443 -api-key cdk_xxx
# Now use -cert commands without -api-key and -host
signercli -cert list
signercli -cert get <id>
signercli -cert upload cert.pem -name "My Cert"
# Or use a named profile
signercli -config set myserver -host https://server:7443 -api-key cdk_xxx
signercli -cert list -profile myserver
For testing -cert upload and other certificate commands, you can create test certificates using OpenSSL.
1. Self-Signed Certificate (Simple)
# Generate RSA key + certificate in one command
openssl req -x509 -newkey rsa:2048 -keyout test_key.pem -out test_cert.pem -days 365 -nodes \
-subj "/C=KR/ST=Seoul/L=Gangnam/O=TestOrg/OU=Dev/CN=Test Certificate"
# Verify certificate
openssl x509 -in test_cert.pem -text -noout
2. Code Signing Certificate
# Generate private key
openssl genrsa -out codesign_key.pem 2048
# Generate certificate with code signing extensions
openssl req -new -x509 -key codesign_key.pem -out codesign_cert.pem -days 365 \
-subj "/C=KR/O=MyCompany/CN=Code Signing Certificate" \
-addext "keyUsage=digitalSignature" \
-addext "extendedKeyUsage=codeSigning"
3. PFX/P12 Bundle (Key + Certificate)
# Create PFX from PEM files
openssl pkcs12 -export -out test_bundle.pfx \
-inkey test_key.pem -in test_cert.pem \
-password pass:test1234
4. DER Format Certificate
# Convert PEM to DER
openssl x509 -in test_cert.pem -outform DER -out test_cert.der
5. Complete Test Script (Linux/macOS)
#!/bin/bash
# create_test_certs.sh
mkdir -p test_certs && cd test_certs
# Basic test certificate
openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 365 -nodes \
-subj "/CN=Test Certificate"
# Code signing certificate
openssl req -x509 -newkey rsa:4096 -keyout codesign_key.pem -out codesign_cert.pem -days 365 -nodes \
-subj "/C=KR/O=TestOrg/CN=Code Signing Test" \
-addext "keyUsage=digitalSignature" \
-addext "extendedKeyUsage=codeSigning"
# PFX bundle
openssl pkcs12 -export -out bundle.pfx -inkey key.pem -in cert.pem -password pass:test1234
# DER format
openssl x509 -in cert.pem -outform DER -out cert.der
echo "Created files:"
ls -la
Note: Windows requires OpenSSL to be installed. You can install it via:
- Git for Windows (includes OpenSSL in Git Bash)
- MSYS2 (
pacman -S openssl)- OpenSSL for Windows
1. Self-Signed Certificate (PowerShell)
# Using Git Bash OpenSSL (adjust path as needed)
& "C:\Program Files\Git\usr\bin\openssl.exe" req -x509 -newkey rsa:2048 `
-keyout test_key.pem -out test_cert.pem -days 365 -nodes `
-subj "/C=KR/ST=Seoul/L=Gangnam/O=TestOrg/OU=Dev/CN=Test Certificate"
# Verify certificate
& "C:\Program Files\Git\usr\bin\openssl.exe" x509 -in test_cert.pem -text -noout
2. Using Windows Native (certreq + PowerShell)
# Create self-signed certificate using PowerShell
$cert = New-SelfSignedCertificate -DnsName "Test Certificate" `
-CertStoreLocation "Cert:\CurrentUser\My" `
-KeyUsage DigitalSignature `
-Type CodeSigningCert `
-NotAfter (Get-Date).AddYears(1)
# Export to PFX
$password = ConvertTo-SecureString -String "test1234" -Force -AsPlainText
Export-PfxCertificate -Cert $cert -FilePath "test_bundle.pfx" -Password $password
# Export certificate only (CER/DER format)
Export-Certificate -Cert $cert -FilePath "test_cert.cer" -Type CERT
# Show certificate info
$cert | Format-List Subject, Thumbprint, NotAfter
3. Complete Test Script (Windows CMD with Git Bash OpenSSL)
@echo off
REM create_test_certs.bat
REM Requires OpenSSL (Git Bash or standalone)
set OPENSSL="C:\Program Files\Git\usr\bin\openssl.exe"
mkdir test_certs 2>nul
cd test_certs
REM Basic test certificate
%OPENSSL% req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 365 -nodes -subj "/CN=Test Certificate"
REM Code signing certificate
%OPENSSL% req -x509 -newkey rsa:4096 -keyout codesign_key.pem -out codesign_cert.pem -days 365 -nodes -subj "/C=KR/O=TestOrg/CN=Code Signing Test" -addext "keyUsage=digitalSignature" -addext "extendedKeyUsage=codeSigning"
REM PFX bundle
%OPENSSL% pkcs12 -export -out bundle.pfx -inkey key.pem -in cert.pem -password pass:test1234
REM DER format
%OPENSSL% x509 -in cert.pem -outform DER -out cert.der
echo Created files:
dir /b
4. Complete Test Script (Windows PowerShell Native)
# create_test_certs.ps1
# Uses Windows native certificate APIs (no OpenSSL required)
$testDir = "test_certs"
New-Item -ItemType Directory -Force -Path $testDir | Out-Null
Set-Location $testDir
$password = ConvertTo-SecureString -String "test1234" -Force -AsPlainText
# Basic test certificate
$basicCert = New-SelfSignedCertificate -DnsName "Test Certificate" `
-CertStoreLocation "Cert:\CurrentUser\My" `
-NotAfter (Get-Date).AddYears(1)
Export-PfxCertificate -Cert $basicCert -FilePath "bundle.pfx" -Password $password
Export-Certificate -Cert $basicCert -FilePath "cert.cer" -Type CERT
Export-Certificate -Cert $basicCert -FilePath "cert.der" -Type CERT
# Code signing certificate
$codeCert = New-SelfSignedCertificate -Subject "CN=Code Signing Test, O=TestOrg, C=KR" `
-CertStoreLocation "Cert:\CurrentUser\My" `
-KeyUsage DigitalSignature `
-Type CodeSigningCert `
-NotAfter (Get-Date).AddYears(1)
Export-PfxCertificate -Cert $codeCert -FilePath "codesign_bundle.pfx" -Password $password
# Clean up from certificate store (optional)
# Remove-Item -Path $basicCert.PSPath
# Remove-Item -Path $codeCert.PSPath
Write-Host "Created files:"
Get-ChildItem
# Upload PEM certificate
signercli -cert upload test_certs/cert.pem -name "Test Cert" -api-key <key> -host https://server:7443
# Upload PFX bundle
signercli -cert upload test_certs/bundle.pfx -name "PFX Bundle" -api-key <key> -host https://server:7443
# Upload DER certificate
signercli -cert upload test_certs/cert.der -name "DER Cert" -api-key <key> -host https://server:7443
| Format | Extension | Description | Created By |
|---|---|---|---|
| PEM | .pem, .crt | Base64 encoded, text format | OpenSSL |
| DER | .der, .cer | Binary format | OpenSSL, Windows |
| PFX/P12 | .pfx, .p12 | Key + Certificate bundle | OpenSSL, Windows |
# List private keys
signercli -privkey list -api-key <key>
# Get private key details
signercli -privkey get <id> -api-key <key>
# Upload private key (default: DB storage)
signercli -privkey upload <file> -api-key <key>
# Upload encrypted private key
signercli -privkey upload <file> -password <pwd> -api-key <key>
# Upload private key to Software HSM
signercli -privkey upload <file> -storage SW_HSM -api-key <key>
# Upload private key to Hardware HSM
signercli -privkey upload <file> -storage HW_HSM -hsm-slot 0 -hsm-pin <pin> -api-key <key>
# Delete private key
signercli -privkey delete <id> -api-key <key>
# Delete HSM private key (PIN required)
signercli -privkey delete <id> -hsm-pin <pin> -api-key <key>
# Link private key to certificate
signercli -privkey link <key-id> <cert-id> -api-key <key>
# Unlink private key from certificate
signercli -privkey unlink <key-id> -api-key <key>
# List public keys
signercli -pubkey list -api-key <key>
# Extract public key from certificate
signercli -pubkey extract <cert-id> -api-key <key>
# Extract with custom name
signercli -pubkey extract <cert-id> -name "Public Key Name" -api-key <key>
# Generate CSR
signercli -csr generate -cn <common-name> -api-key <key>
# Generate CSR with full subject
signercli -csr generate \
-cn example.com \
-c KR \
-st Seoul \
-l Gangnam \
-org "Example Corp" \
-ou "IT Department" \
-email admin@example.com \
-keysize 4096 \
-api-key <key>
# Save CSR to file
signercli -csr generate -cn example.com -o <dir> -api-key <key>
Direct management of Let's Encrypt SSL certificates stored on the server. Requires SYSTEM_ADMIN role or explicit letsencrypt permission.
Note: This command directly accesses Let's Encrypt certificates stored on the server, while
-cert-distis for distributing certificates to external servers/devices.
Authentication:
You can authenticate using either method:
# Method 1: Login first, then use commands without API key
signercli -login https://signer.example.com:7443 admin
signercli -letsencrypt list
# Method 2: Use API key directly
signercli -letsencrypt list -api-key <key>
Access Control:
| Authentication | Condition | Access |
|---|---|---|
| JWT | role = SYSTEM_ADMIN | ✅ Allowed |
| JWT | role = OPERATION_MANAGER or USER | ❌ Denied |
| API Key (inherited) | linkedUserRole = SYSTEM_ADMIN | ✅ Allowed |
| API Key (inherited) | linkedUserRole ≠ SYSTEM_ADMIN | ❌ Denied |
| API Key (explicit) | permissions includes letsencrypt or all | ✅ Allowed |
| API Key (explicit) | permissions excludes letsencrypt | ❌ Denied |
Commands:
| Command | Description |
|---|---|
list | List Let's Encrypt certificates |
get <id> | Get certificate details |
download <id> | Download certificate files |
request | Request new certificate (HTTP-01 or DNS-01) |
dns-request | Start DNS-01 challenge (outputs challenge ID) |
dns-request -interactive | DNS-01 challenge (interactive mode) |
dns-complete | Complete DNS-01 challenge |
dns-providers | List available DNS providers |
renew <id> | Renew certificate (automatic) |
renew-dns <id> | Start manual DNS-01 renewal (outputs challenge ID) |
renew-dns <id> -interactive | Manual DNS-01 renewal (interactive mode) |
delete <id> | Delete certificate |
auto-renewal <id> | Enable/disable auto-renewal |
activate <id> | Set certificate as Signer server's SSL certificate |
List/Get/Download Options:
| Option | Description | Default |
|---|---|---|
-api-key <key> | API key (optional if logged in) | - |
-host <url> | Server URL | https://localhost:7443 |
-format <type> | Output format: text, json | text |
-env <environment> | Filter by environment: staging, production | - |
-domain <pattern> | Filter by domain (supports * wildcard, e.g., *.example.com) | - |
-type <type> | Download type: cert, chain, fullchain, key, all | fullchain |
-o <dir> | Output directory for downloads | Current directory |
-naming <style> | Filename style: letsencrypt or domain | letsencrypt |
Request Options:
| Option | Description | Default |
|---|---|---|
-domain <domain> | Domain name for the certificate (required) | - |
-email <email> | Contact email for Let's Encrypt account (required) | - |
-agree-tos | Agree to Let's Encrypt Terms of Service (required) | - |
-env <environment> | Environment: staging, production | staging |
-key-type <type> | Key type: RSA, ECDSA | RSA |
-keysize <bits> | Key size: 2048, 4096, etc. | 2048 |
-san <domains> | Subject Alternative Names (comma-separated) | - |
-challenge <type> | Challenge type: http-01, dns-01 | http-01 |
-dns-provider <mode> | DNS provider mode: auto, selected (for dns-01) | auto |
-provider-id <id> | DNS Provider ID (auto-sets -dns-provider to 'selected') | - |
DNS-01 Challenge Options (for dns-request/dns-complete):
| Option | Description | Default |
|---|---|---|
-interactive, -i | Interactive mode: wait for Enter, then complete (dns-request) | - |
-challenge-id <id> | Challenge ID from dns-request (for dns-complete) | - |
Auto-Renewal Options:
| Option | Description |
|---|---|
-enable | Enable auto-renewal |
-disable | Disable auto-renewal |
# List Let's Encrypt certificates
signercli -letsencrypt list # Using login token
signercli -letsencrypt list -api-key <key> # Using API key
# Filter by environment
signercli -letsencrypt list -env production
signercli -letsencrypt list -env staging
# Filter by domain (partial match or wildcard)
signercli -letsencrypt list -domain example.com
signercli -letsencrypt list -domain api # Matches api.example.com, etc.
signercli -letsencrypt list -domain "*.example.com" # Matches wildcard certificates
# Combine filters
signercli -letsencrypt list -env production -domain example.com
# Get certificate details
signercli -letsencrypt get <id>
# Download certificate (fullchain by default)
signercli -letsencrypt download <id>
# Download specific type
signercli -letsencrypt download <id> -type cert # Certificate only
signercli -letsencrypt download <id> -type chain # Chain only
signercli -letsencrypt download <id> -type fullchain # Full chain (default)
signercli -letsencrypt download <id> -type key # Private key
signercli -letsencrypt download <id> -type all # All files
# Download to specific directory (default: cert.pem, privkey.pem, etc.)
signercli -letsencrypt download <id> -type all -o /etc/ssl
# Download with domain-based naming (<domain>.crt, <domain>.key, etc.)
signercli -letsencrypt download <id> -type all -o /etc/ssl -naming domain
Download Types:
| Type | Description | Let's Encrypt (default) | Domain Style |
|---|---|---|---|
cert | Certificate only | cert.pem | <domain>.crt |
chain | Intermediate chain | chain.pem | <domain>.chain.crt |
fullchain | Certificate + chain (default) | fullchain.pem | <domain>.fullchain.crt |
key | Private key | privkey.pem | <domain>.key |
all | All files | All above files | All above files |
Output Options:
# JSON format output
signercli -letsencrypt list -format json
# Table format output
signercli -letsencrypt list -format table
Examples:
# Login first (recommended for interactive use)
signercli -login https://signer.example.com:7443 admin
# List all production certificates
signercli -letsencrypt list -env production
# List certificates for a specific domain
signercli -letsencrypt list -domain example.com
# Get specific certificate details
signercli -letsencrypt get 6789abcd
# Download fullchain to /etc/nginx/ssl
signercli -letsencrypt download 6789abcd -type fullchain -o /etc/nginx/ssl
# Download all files for Nginx configuration
signercli -letsencrypt download 6789abcd -type all -o /etc/nginx/ssl
# Using API key (for automation/scripts)
signercli -letsencrypt list -env production -api-key cdk_xxx -host https://signer.example.com:7443
# --- HTTP-01 Challenge (default) ---
# Request new certificate (staging environment - for testing)
signercli -letsencrypt request -domain example.com -email admin@example.com -agree-tos
# Request production certificate
signercli -letsencrypt request -domain example.com -email admin@example.com -agree-tos -env production
# Request certificate with Subject Alternative Names
signercli -letsencrypt request -domain example.com -san "www.example.com,api.example.com" -email admin@example.com -agree-tos
# --- DNS-01 Challenge with DNS Provider ---
# Auto-detect DNS provider for domain (default when using dns-01)
signercli -letsencrypt request -domain example.com -email admin@example.com -agree-tos \
-challenge dns-01
# Use specific DNS provider (provider-id auto-sets mode to 'selected')
signercli -letsencrypt request -domain example.com -email admin@example.com -agree-tos \
-challenge dns-01 -provider-id 6789abc
# Wildcard certificate with DNS provider (auto mode)
signercli -letsencrypt request -domain "*.example.com" -email admin@example.com -agree-tos \
-challenge dns-01 -env production
# --- DNS-01 Challenge (Manual - Two-step process) ---
# Step 1: Start DNS challenge (get TXT records to add)
signercli -letsencrypt dns-request -domain example.com -email admin@example.com -agree-tos
# Step 2: After adding TXT records to DNS, complete the challenge
signercli -letsencrypt dns-complete -challenge-id <challenge-id>
# --- DNS-01 Challenge (Manual - Interactive mode) ---
# Single command that waits for Enter and completes automatically
signercli -letsencrypt dns-request -domain example.com -email admin@example.com -agree-tos -interactive
# --- DNS Provider Management ---
# List available DNS providers
signercli -letsencrypt dns-providers
# --- Certificate Renewal ---
# Renew certificate (automatic - for HTTP-01 or auto DNS-01)
signercli -letsencrypt renew 6789abcd
# --- Manual DNS-01 Renewal (Two-step process) ---
# Step 1: Start renewal (get DNS records and challenge ID)
signercli -letsencrypt renew-dns 6789abcd
# Step 2: After adding TXT records to DNS, complete the renewal
signercli -letsencrypt dns-complete -challenge-id <challenge-id>
# --- Manual DNS-01 Renewal (Interactive mode) ---
# Single command that waits for Enter and completes automatically
signercli -letsencrypt renew-dns 6789abcd -interactive
# Delete certificate
signercli -letsencrypt delete 6789abcd
# Enable auto-renewal
signercli -letsencrypt auto-renewal 6789abcd -enable
# Disable auto-renewal
signercli -letsencrypt auto-renewal 6789abcd -disable
# --- Activating Server SSL Certificate ---
# Activate certificate for HTTPS server
signercli -letsencrypt activate 6789abcd
Important: About the 'activate' command
The
activatecommand sets the specified Let's Encrypt certificate as the Signer server's own SSL certificate. This means that after activation:
- The Signer server will use this certificate for HTTPS connections
- Clients connecting to the Signer server will see this certificate
This does NOT mean:
- ❌ Enabling or disabling the certificate itself
- ❌ Making the certificate "active" vs "inactive"
- ❌ Publishing or unpublishing the certificate
All issued certificates remain valid and usable regardless of activation status. The
activatecommand is only for configuring which certificate the Signer server uses for its own HTTPS endpoint.
Certificate Issuance/Renewal Notes:
| Scenario | Command | Description |
|---|---|---|
| New Certificate | ||
| DNS-01 manual (scripted) | dns-request + dns-complete | Two-step process for automation |
| DNS-01 manual (interactive) | dns-request -interactive | Single command with Enter prompt |
| Certificate Renewal | ||
| HTTP-01 challenge | renew | Automatic renewal via HTTP validation |
| DNS-01 with provider | renew | Automatic renewal via DNS API |
| DNS-01 manual (scripted) | renew-dns + dns-complete | Two-step process for automation |
| DNS-01 manual (interactive) | renew-dns -interactive | Single command with Enter prompt |
| Renewal failed | renew-dns | Use when renew shows "Manual DNS renewal required" |
Challenge Types:
| Challenge | Description | Use Case |
|---|---|---|
| HTTP-01 | Validates via HTTP on port 80 | Standard domains, internet-accessible servers |
| DNS-01 | Validates via DNS TXT record | Wildcard certs, internal servers, port 80 blocked |
DNS Provider Modes:
| Mode | Description |
|---|---|
auto | Auto-detect DNS provider based on domain (default for dns-01) |
selected | Use specific provider (auto-set when -provider-id is provided) |
| Manual | Use dns-request/dns-complete commands |
Note: When using
-challenge dns-01:
- If
-dns-provideris not specified, it defaults toauto- If
-provider-idis specified,-dns-provideris automatically set toselected
Supported DNS Providers:
Notes:
*.example.com).| Option | Description | Default |
|---|---|---|
-api-key <key> | API key (optional for -letsencrypt if logged in) | - |
-host <url> | Signer Server URL | https://localhost:7443 |
-profile <name> | Use settings from config profile | default |
-format <type> | Output format (json, pem, der) | text |
-o <dir> | Output directory | Current directory |
-name <name> | Name for upload/create | Filename |
-desc <text> | Description | - |
-password <pwd> | PFX/encrypted key password | - |
-storage <type> | Storage type: DB, SW_HSM, HW_HSM | DB |
-hsm-slot <id> | HSM slot ID (required for HW_HSM) | - |
-hsm-pin <pin> | HSM PIN (for HSM objects) | - |
-include-chain | Include certificate chain | - |
-delete-related | Delete related private key | - |
For system-wide DLL access (required for signtool integration), install DLLs to System32:
# Both tools auto-request UAC elevation when needed
signercli -install
signer -install
# To remove DLLs from System32
signercli -uninstall
signer -uninstall
What gets installed:
otpkey.dll → C:\Windows\System32\otpkey.dllCertchip.dll → C:\Windows\System32\Certchip.dllWhen to use:
signtool.exe with the Certchip KSP providerconst signer = require('@certchip/signer');
// Login
await signer.login('https://signer.example.com', 'username', {
keyPath: '~/.ssh/id_ed25519',
expires: '24h',
certId: 'abc123',
includeChain: true
});
// Sign a file
await signer.sign('myapp.exe', {
output: 'myapp_signed.exe',
hashAlgorithm: 'sha256',
timestampUrl: 'http://timestamp.digicert.com'
});
// Verify signature
const result = await signer.verify('myapp_signed.exe');
console.log(result.valid ? 'Valid' : 'Invalid');
// Configuration
await signer.config('set', 'production', {
host: 'https://signer.example.com',
username: 'john',
expires: '12h'
});
// List certificates
const certs = await signer.listCertificates();
// Logout
await signer.logout();
Create reusable signing profiles:
# Create a code signing profile
signercli -config set production \
-host https://signer.example.com \
-username john \
-ssh-key-path ~/.ssh/id_ed25519 \
-expires 24h \
-cert-id abc123 \
-include-chain \
-timestamp-url http://timestamp.digicert.com \
-hash-algorithm sha256
# Create a document signing profile with visual signature
signercli -config set pdf-signing \
-host https://signer.example.com \
-username john \
-doc-style qrcode \
-doc-position bottom-right \
-doc-sig-position center \
-doc-font-size 12 \
-doc-opacity 0.8
# Create an automation profile with JSON output
signercli -config set automation \
-host https://signer.example.com \
-output-format json
# Create a profile with API key (no login required)
signercli -config set cert-api \
-host https://signer.example.com:7443 \
-api-key cdk_e2f369e7c85bfa7835d375f6b088f15dac2c2d8ebeb0815c392a6d6b34ee916f
# Use the profile
signercli -login -profile production
signercli myapp.exe -profile production # Implicit form
signercli -sign myapp.exe -profile production # Explicit form (same result)
signercli document.pdf -profile pdf-signing
signercli -verify myapp.exe -profile automation # Outputs JSON automatically
# Use API key profile (no login required)
signercli -cert list -profile cert-api
signercli -cert get <id> -profile cert-api
signercli -cert upload cert.pem -profile cert-api
| Type | Extensions | Method |
|---|---|---|
| Code | .exe, .dll, .sys, .ocx, .msi, .msp, .cab | Authenticode |
| Document | Server-based with visual signature | |
| Script | .ps1, .vbs | Authenticode |
| Java | .jar | JAR signing |
| Text/Source | .js, .ts, .py, .java, .c, .cpp, .go, .rs, .sh, .yml, .json, .xml, .html, .sql, .md, .txt | Embedded signature |
@certchip/signer/
├── lib/
│ ├── index.js # Node.js API
│ └── index.d.ts # TypeScript definitions
└── bin/
├── signercli.js # Cross-platform wrapper
├── signer.js # Windows KSP wrapper
├── linux-x64/
│ └── signercli # Fully static binary (no dynamic dependencies)
└── win32-x64/
├── signercli.exe # Static build
├── signer.exe # Static build
├── otpkey.dll # Static linked
└── Certchip.dll # KSP provider
| signercli | signer | |
|---|---|---|
| Platform | Windows, Linux, macOS | Windows only |
| Dependencies | None (static build) | otpkey.dll, Certchip.dll |
| Size | 9.3 MB | 420 KB + 6.9 MB DLLs |
| Signing method | Direct (via server API) | Direct OR via Windows crypto (signtool) |
| Windows KSP | No | Yes |
| signtool compatible | No | Yes |
| UAC auto-elevation | Yes | Yes |
| Use case | CI/CD, cross-platform | Windows developers, signtool |
#!/bin/bash
set -e
# Login with JSON output for parsing
result=$(signercli -login "$SIGNER_URL" -user "$SIGNER_USER" -pw "$SIGNER_PW" -format json)
if ! echo "$result" | jq -e '.success' > /dev/null; then
echo "Login failed: $(echo "$result" | jq -r '.error')"
exit 1
fi
# Sign all executables
for exe in dist/*.exe; do
signercli "$exe"
done
# Logout with JSON output
signercli -logout -format json
#!/bin/bash
set -e
# Sign and verify with JSON output
signercli -login "$SIGNER_URL" -user "$SIGNER_USER" -pw "$SIGNER_PW" -format json
for exe in dist/*.exe; do
signercli "$exe"
# Verify and parse JSON result
verify_result=$(signercli -verify "$exe" -format json)
status=$(echo "$verify_result" | jq -r '.status')
if [ "$status" != "valid" ]; then
echo "Verification failed for $exe"
exit 1
fi
done
signercli -logout -format json
import * as signer from '@certchip/signer';
async function signRelease() {
await signer.login('https://signer.example.com', 'username');
const result = await signer.sign('app.exe', {
output: 'app_signed.exe',
hashAlgorithm: 'sha256'
});
if (result.success) {
console.log('Signed:', result.outputPath);
}
await signer.logout();
}
# Login
signercli -login https://signer.example.com username
# Sign PDF with QR code signature
signercli document.pdf \
-doc-style qrcode \
-doc-position bottom-right \
-o document_signed.pdf
# Sign PDF with watermark
signercli contract.pdf \
-doc-style watermark \
-doc-position center \
-doc-opacity 0.3
REM First-time setup (run as Administrator):
REM 1. Install DLLs to System32
signercli -install
REM 2. Register KSP provider
signer -register
REM Daily usage:
REM Login to get certificate
signer -login https://signer.example.com username
REM Sign with signtool
signtool sign /n "Your Certificate" /fd sha256 /tr http://timestamp.digicert.com myapp.exe
REM Verify
signtool verify /pa myapp.exe
REM Logout
signer -logout
REM To uninstall:
signer -unregister
signercli -uninstall
# Generate Ed25519 key (if needed)
ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519
# Login with default key
signercli -login https://server.com username
# Login with specific key
signercli -login https://server.com username -key ~/.ssh/id_rsa
signercli -login https://server.com -user admin -pw password
| Variable | Description |
|---|---|
SIGNER_URL | Default server URL |
SIGNER_USER | Default username |
SIGNER_KEY_PATH | Default SSH key path |
SIGNER_CERT_ID | Default certificate ID |
The signer command requires Windows KSP integration. Use signercli for cross-platform signing.
The signer.exe requires otpkey.dll and Certchip.dll. These are automatically included when installed via npm. No additional MSYS2 or system DLLs are required.
For signtool integration or system-wide access, install DLLs to System32:
signercli -install
The -install command requires Administrator privileges. Both signercli and signer will automatically request UAC elevation. If the UAC prompt is cancelled, run the command prompt as Administrator.
Login again:
signercli -login https://server.com username
On Linux/macOS, ensure the binary is executable:
chmod +x node_modules/@certchip/signer/bin/*/signercli
Build a fully static binary for Linux distribution (no dynamic library dependencies):
cd core/signer-cli
# Fullstatic build (auto-builds libcurl.a if missing)
./build_fullstatic_linux_x64.sh
# Or step by step:
./build_fullstatic_linux_x64.sh --check # Check static library dependencies
./build_fullstatic_linux_x64.sh --build-curl # Build static libcurl if missing
./build_fullstatic_linux_x64.sh # Build fullstatic binary
# Output: bin/linux-x64/signercli (fully static, no dynamic dependencies)
Required static libraries (in ../../libs/):
libssl.a, libcrypto.a)libcjson.a)libjson-c.a)libcurl.a)libotpkey.a)cd core/signer-cli
# Static build for npm package
make -f Makefile.msys2 STATIC_CURL=1 RELEASE=1
# Build + copy dependencies for npm
make -f Makefile.msys2 npm-package
cd core/signer-cli
make # Debug build (auto-detects platform)
make RELEASE=1 # Release build
Copyright (c) 2026 Certchip. All rights reserved.
FAQs
Cross-platform code and document signing CLI tool
We found that @certchip/signer demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
The Axios compromise shows how time-dependent dependency resolution makes exposure harder to detect and contain.

Research
A supply chain attack on Axios introduced a malicious dependency, plain-crypto-js@4.2.1, published minutes earlier and absent from the project’s GitHub releases.

Research
Malicious versions of the Telnyx Python SDK on PyPI delivered credential-stealing malware via a multi-stage supply chain attack.