Introduction
Certificate Transparency (CT) is a system that logs all publicly trusted SSL certificates in publicly auditable logs. Modern browsers (especially Chrome) require certificates to have Signed Certificate Timestamps (SCTs) proving they were logged. Missing or invalid SCTs cause browser rejection with CT-specific errors. Understanding CT requirements helps resolve these advanced certificate validation issues.
Symptoms
- Chrome error:
NET::ERR_CERTIFICATE_TRANSPARENCY_REQUIRED - Browser rejection with CT-specific message
- Certificate works in some browsers but not Chrome
- SSL Labs shows CT issues in validation
- Error: "Certificate does not have enough SCTs"
- Certificate issued but not appearing in CT logs
- Chrome CT policy not satisfied
Common Causes
- Certificate issued by CA not participating in CT
- CA didn't embed SCTs in certificate
- OCSP response missing SCT information
- Certificate too old (pre-CT policy era)
- CA's CT log submission failed
- Insufficient number of SCTs for certificate validity period
- TLS extension for SCT not sent by server
- Certificate issuance timing issues
Step-by-Step Fix
Step 1: Check Current CT Status
```bash # Check certificate for embedded SCTs openssl x509 -in certificate.crt -noout -text | grep -A 20 "CT Precertificate SCTs"
# Check SCT list extension openssl x509 -in certificate.crt -noout -text | grep -i "Signed Certificate Timestamp List"
# Check via SSL Labs # https://www.ssllabs.com/ssltest/analyze.html?d=example.com # Look for "Certificate Transparency" section
# Check if certificate appears in CT logs curl -s "https://crt.sh/?q=$(openssl x509 -in certificate.crt -noout -fingerprint -sha256 | cut -d= -f2 | tr -d ':')" | grep example.com ```
Step 2: Understand CT Requirements
```bash # Chrome CT policy requirements: # Certificates valid after April 2018 must have: # - At least 2 SCTs from different logs (if validity <= 180 days) # - At least 3 SCTs from different logs (if validity > 180 days)
# SCT delivery methods: # 1. Embedded in certificate (X.509v3 extension) # 2. OCSP stapling with SCT extension # 3. TLS extension (signed_certificate_timestamp)
# Check certificate validity period openssl x509 -in certificate.crt -noout -dates openssl x509 -in certificate.crt -noout -text | grep -A 2 Validity ```
Step 3: Check SCT Count
```bash # Count embedded SCTs openssl x509 -in certificate.crt -noout -text | grep -c "SCT list"
# Detailed SCT information openssl x509 -in certificate.crt -noout -text | grep -B 2 -A 5 "Certificate Transparency"
# Check minimum required based on validity VALIDITY_DAYS=$(( ($(date -d "$(openssl x509 -in certificate.crt -noout -enddate | cut -d= -f2)" +%s) - $(date -d "$(openssl x509 -in certificate.crt -noout -startdate | cut -d= -f2)" +%s)) / 86400 ))
echo "Certificate validity: $VALIDITY_DAYS days" if [ $VALIDITY_DAYS -le 180 ]; then echo "Requires at least 2 SCTs" else echo "Requires at least 3 SCTs" fi ```
Step 4: Get New Certificate from Compliant CA
```bash # If certificate lacks SCTs, need to reissue from CT-compliant CA
# Let's Encrypt automatically handles CT certbot certonly -d example.com -d www.example.com
# Commercial CAs: # Ensure CA supports CT and embeds SCTs # Most major CAs (DigiCert, Sectigo, GlobalSign) are CT-compliant
# Check CA's CT policy documentation before ordering ```
Step 5: Configure OCSP Stapling with SCTs
```nginx # Nginx - enable OCSP stapling (may include SCTs) ssl_stapling on; ssl_stapling_verify on; resolver 8.8.8.8 8.8.4.4 valid=300s;
# For certificates that deliver SCTs via OCSP # Stapling OCSP response includes SCT extension
# Check OCSP response for SCTs openssl ocsp -issuer chain.crt -cert server.crt \ -url $(openssl x509 -in server.crt -noout -ocsp_uri) \ -resp_text | grep -i "SCT" ```
# Test stapling
openssl s_client -connect example.com:443 -servername example.com -status 2>&1 | grep -i "OCSP\|SCT"Step 6: Enable TLS SCT Extension
```nginx # Some servers can send SCTs via TLS extension # If you have SCT files from CA:
# Nginx doesn't directly support TLS SCT extension yet # SCTs must be embedded in certificate or via OCSP
# Check if your CA provides SCT files # Contact CA for delivery method options ```
Step 7: Verify CT After Reissuing
```bash # After obtaining new certificate:
# Check embedded SCTs openssl x509 -in new-cert.crt -noout -text | grep -A 5 "Signed Certificate Timestamp"
# Verify in CT logs curl -s "https://crt.sh/?q=new-cert-fingerprint"
# Test in Chrome # Chrome should accept certificate without CT error
# SSL Labs comprehensive CT check # https://www.ssllabs.com/ssltest/ ```
Step 8: Monitor CT Compliance
```bash # Set up monitoring for CT issues # Regular SSL Labs scans check CT
# Simple CT check script: cat > /usr/local/bin/check-ct.sh << 'EOF' #!/bin/bash DOMAIN="example.com"
# Check certificate has SCT extension SCTS=$(openssl s_client -connect $DOMAIN:443 -servername $DOMAIN 2>/dev/null | openssl x509 -noout -text | grep -c "Signed Certificate Timestamp")
if [ $SCTS -lt 2 ]; then echo "Warning: Certificate for $DOMAIN has only $SCTS SCTs (minimum 2 required)" fi
# Check CT logs via crt.sh crt_query="https://crt.sh/?q=$DOMAIN&output=json" count=$(curl -s "$crt_query" | jq length) echo "Certificates in CT logs: $count" EOF chmod +x /usr/local/bin/check-ct.sh ```
Step 9: Handle CT Policy Updates
```bash # Chrome CT policy evolves # Monitor for policy changes at: # https://www.chromium.org/Home/chromium-security/certificate-transparency
# Key dates: # April 2018: CT required for all new certificates # Future: More logs required, stricter validation
# Ensure certificate management accounts for future requirements # Use CAs that proactively comply with CT updates ```
Step 10: Document CT Process
```bash # Document for your team: # - Which CA you use and their CT compliance # - SCT delivery method (embedded, OCSP, TLS extension) # - How to verify CT before deployment # - What to do if CT errors occur
# Create CT checklist for certificate deployments: # 1. Verify CA is CT-compliant # 2. Check embedded SCTs count # 3. Verify in crt.sh logs # 4. Test in Chrome before production # 5. Monitor for CT policy changes ```
Common Pitfalls
- Using certificate from CA that doesn't participate in CT
- Certificate issued before CT policy but still in use
- Not enough SCTs for certificate validity period
- OCSP stapling disabled, missing SCT delivery method
- Assuming all browsers have same CT requirements
- Not monitoring for CT policy changes
- Testing only in Firefox, missing Chrome CT issues
Best Practices
- Use CT-compliant CA (Let's Encrypt, major commercial CAs)
- Verify SCTs before deploying certificate
- Enable OCSP stapling for additional SCT delivery
- Monitor crt.sh for certificate log entries
- Test in Chrome specifically for CT compliance
- Keep up with Chrome CT policy updates
- Document CT verification process
Related Issues
- SSL Certificate Not Trusted
- OCSP Stapling Error
- SSL Certificate Chain Incomplete
- SSL Certificate Revoked