Intermediate certificates act as a bridge between root certificates and end-entity certificates. They're crucial for establishing trust chains in SSL/TLS implementations. While you can't directly "buy" an intermediate certificate like a standard SSL cert, you can obtain one through proper channels from Certificate Authorities (CAs).
Wildcard certificates (*.example.com) have limitations:
// Example of wildcard limitation
const domain = 'sub.example.com';
const wildcardCert = '*.example.com';
console.log(wildcardCert.validFor(domain)); // True for any single subdomain
But they don't allow you to create new certificates programmatically, which is what you need for dynamic subdomain signing.
Major CAs offer solutions for this use case:
- DigiCert: Certificate Signing Services
- Sectigo: Private PKI solutions
- GlobalSign: Atlas PKI platform
These typically require enterprise agreements rather than simple purchases.
Here's how you might implement subdomain certificate signing with an intermediate cert:
# Python example using OpenSSL
from OpenSSL import crypto
# Load your intermediate cert and key
with open('intermediate.pem', 'rt') as f:
intermediate_cert = crypto.load_certificate(crypto.FILETYPE_PEM, f.read())
with open('intermediate.key', 'rt') as f:
intermediate_key = crypto.load_privatekey(crypto.FILETYPE_PEM, f.read())
# Create new cert for subdomain
cert = crypto.X509()
cert.get_subject().CN = 'dynamic-sub.example.com'
cert.set_serial_number(1000)
cert.gmtime_adj_notBefore(0)
cert.gmtime_adj_notAfter(365*24*60*60)
cert.set_issuer(intermediate_cert.get_subject())
cert.set_pubkey(intermediate_cert.get_pubkey())
cert.sign(intermediate_key, 'sha256')
For browser recognition:
- Your intermediate must chain to a trusted root
- OCSP/CRL endpoints must be properly configured
- Certificate Transparency logs should be submitted
Test with SSL Labs' test tool to verify trust.
If obtaining an intermediate proves difficult:
// Using Let's Encrypt with DNS challenges
const acme = require('acme-client');
const client = new acme.Client({
directoryUrl: acme.directory.letsencrypt.production
});
// Would need to automate for each new subdomain
This provides free certificates but requires validation for each subdomain.
When implementing this solution:
- Store private keys in HSM or secure key storage
- Implement proper certificate revocation
- Monitor certificate expiration
- Use strong cryptographic algorithms (minimum SHA-256)
Many developers assume they can simply purchase an intermediate certificate authority (CA) certificate to sign their own subdomain certificates. However, the public PKI ecosystem doesn't work this way for security reasons. Browser-trusted intermediate certificates are strictly controlled by root certificate authorities.
Commercial CAs like DigiCert, Sectigo, or Let's Encrypt won't sell intermediate certificates because:
1. It would undermine the chain of trust
2. Browsers explicitly validate the entire certificate chain
3. Intermediate CAs must pass rigorous audits (WebTrust)
For subdomain management without wildcards, consider:
Option 1: ACME Automation
Use Let's Encrypt with DNS-01 challenges for automated subdomain certificates:
certbot certonly --manual --preferred-challenges=dns \
-d sub1.example.com -d sub2.example.com
Option 2: Private PKI
Set up an internal CA for development (browsers won't trust it by default):
# Generate root CA
openssl req -x509 -sha256 -days 1825 -newkey rsa:2048 \
-keyout rootCA.key -out rootCA.crt
# Generate intermediate CA
openssl req -new -newkey rsa:2048 -keyout intermediate.key \
-out intermediate.csr
openssl x509 -req -CA rootCA.crt -CAkey rootCA.key \
-in intermediate.csr -out intermediate.crt -days 365 -CAcreateserial
Large organizations can apply to become subordinate CAs under existing roots through programs like:
- Microsoft's Windows Root Certificate Program
- Mozilla's CA Certificate Program
- Google's Root Certificate Policy
These require extensive audits and minimum $50M in liability insurance.
All publicly trusted certificates must be logged in CT systems. You can monitor your domains using:
openssl s_client -connect example.com:443 -servername example.com \
2>/dev/null | openssl x509 -text | grep -i "ct log"