Webtool to extract info X.509 certificates, including public keys, private keys, and JSON Web Keys
10K+
A secure web application for extracting information from X.509 certificates, including public keys, private keys, and JSON Web Keys (JWK). This tool is perfect for developers working with certificates and cryptographic operations.
docker run -d -p 8080:9080 jtenorio/certificate-reader:latest
Access the application at http://localhost:8080ā
docker run -d \
-p 8080:9080 \
-e ASPNETCORE_ENVIRONMENT=Production \
jtenorio/certificate-reader:latest
version: '3.8'
services:
certificate-reader:
image: jtenorio/certificate-reader:latest
container_name: certificate-reader
ports:
- "8080:9080"
environment:
- ASPNETCORE_ENVIRONMENT=Production
- ASPNETCORE_URLS=http://+:9080
restart: unless-stopped
healthcheck:
test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost:9080/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
This example shows how to deploy with Nginx handling SSL/TLS termination. The application correctly handles forwarded headers and doesn't enforce HTTPS redirection.
docker-compose.yml:
version: '3.8'
services:
certificate-reader:
image: jtenorio/certificate-reader:latest
container_name: certificate-reader
volumes:
# Mount custom appsettings.json with SSL termination enabled
- ./appsettings.Production.json:/app/appsettings.json:ro
environment:
- ASPNETCORE_ENVIRONMENT=Production
- ASPNETCORE_URLS=http://+:9080
networks:
- cert-reader-network
restart: unless-stopped
healthcheck:
test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost:9080/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
nginx:
image: nginx:alpine
container_name: nginx-proxy
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
- ./ssl:/etc/nginx/ssl:ro # Your SSL certificates
networks:
- cert-reader-network
depends_on:
- certificate-reader
restart: unless-stopped
networks:
cert-reader-network:
driver: bridge
appsettings.Production.json:
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "localhost;yourdomain.com;*.yourdomain.com",
"ReverseProxy": {
"EnableForwardedHeaders": true,
"ForwardLimit": 1,
"SslTerminatedAtProxy": true,
"TrustForwardedProto": true,
"EnableDebugLogging": false
}
}
nginx.conf:
events {
worker_connections 1024;
}
http {
upstream certificate-reader {
server certificate-reader:9080;
}
# HTTP - Redirect to HTTPS
server {
listen 80;
server_name yourdomain.com;
return 301 https://$server_name$request_uri;
}
# HTTPS - SSL Termination
server {
listen 443 ssl http2;
server_name yourdomain.com;
ssl_certificate /etc/nginx/ssl/cert.pem;
ssl_certificate_key /etc/nginx/ssl/key.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
# Security headers
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Frame-Options "DENY" always;
add_header X-Content-Type-Options "nosniff" always;
location / {
proxy_pass http://certificate-reader;
# Essential forwarded headers for SSL termination
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Port $server_port;
# WebSocket support (if needed)
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
# Timeouts
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
}
# Health check endpoint
location /health {
proxy_pass http://certificate-reader/health;
access_log off;
}
}
}
Override settings using environment variables (useful for container orchestration):
version: '3.8'
services:
certificate-reader:
image: jtenorio/certificate-reader:latest
container_name: certificate-reader
ports:
- "8080:9080"
environment:
- ASPNETCORE_ENVIRONMENT=Production
- ASPNETCORE_URLS=http://+:9080
# Override appsettings.json using environment variables
- ReverseProxy__EnableForwardedHeaders=true
- ReverseProxy__SslTerminatedAtProxy=true
- ReverseProxy__TrustForwardedProto=true
- ReverseProxy__ForwardLimit=1
- AllowedHosts=localhost;yourdomain.com;*.yourdomain.com
- Logging__LogLevel__Default=Information
restart: unless-stopped
Using Certbot for automatic SSL certificate management:
version: '3.8'
services:
certificate-reader:
image: jtenorio/certificate-reader:latest
container_name: certificate-reader
volumes:
- ./appsettings.Production.json:/app/appsettings.json:ro
environment:
- ASPNETCORE_ENVIRONMENT=Production
- ASPNETCORE_URLS=http://+:9080
networks:
- cert-reader-network
restart: unless-stopped
nginx:
image: nginx:alpine
container_name: nginx-proxy
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
- certbot-etc:/etc/letsencrypt
- certbot-var:/var/lib/letsencrypt
- ./dhparam:/etc/ssl/certs
networks:
- cert-reader-network
depends_on:
- certificate-reader
restart: unless-stopped
certbot:
image: certbot/certbot
container_name: certbot
volumes:
- certbot-etc:/etc/letsencrypt
- certbot-var:/var/lib/letsencrypt
- ./webroot:/var/www/html
depends_on:
- nginx
command: certonly --webroot --webroot-path=/var/www/html --email [email protected] --agree-tos --no-eff-email --force-renewal -d yourdomain.com
networks:
cert-reader-network:
driver: bridge
volumes:
certbot-etc:
certbot-var:
version: '3.8'
services:
certificate-reader:
image: jtenorio/certificate-reader:latest
container_name: certificate-reader
environment:
- ASPNETCORE_ENVIRONMENT=Production
- ASPNETCORE_URLS=http://+:9080
- ReverseProxy__EnableForwardedHeaders=true
- ReverseProxy__SslTerminatedAtProxy=true
- ReverseProxy__TrustForwardedProto=true
labels:
- "traefik.enable=true"
- "traefik.http.routers.cert-reader.rule=Host(`yourdomain.com`)"
- "traefik.http.routers.cert-reader.entrypoints=websecure"
- "traefik.http.routers.cert-reader.tls=true"
- "traefik.http.routers.cert-reader.tls.certresolver=letsencrypt"
- "traefik.http.services.cert-reader.loadbalancer.server.port=9080"
networks:
- traefik
restart: unless-stopped
networks:
traefik:
external: true
For local development without SSL:
version: '3.8'
services:
certificate-reader:
image: jtenorio/certificate-reader:latest
container_name: certificate-reader-dev
ports:
- "8080:9080"
environment:
- ASPNETCORE_ENVIRONMENT=Development
- ASPNETCORE_URLS=http://+:9080
- ReverseProxy__EnableForwardedHeaders=false
- ReverseProxy__SslTerminatedAtProxy=false
restart: unless-stopped
Mount a custom appsettings.json file:
volumes:
- ./appsettings.Production.json:/app/appsettings.json:ro
Use environment variables with double underscore notation:
environment:
- ReverseProxy__SslTerminatedAtProxy=true
- ReverseProxy__EnableForwardedHeaders=true
- ReverseProxy__TrustForwardedProto=true
- AllowedHosts=yourdomain.com
version: '3.8'
services:
certificate-reader:
image: jtenorio/certificate-reader:latest
secrets:
- appsettings
environment:
- ASPNETCORE_ENVIRONMENT=Production
command: sh -c "cp /run/secrets/appsettings /app/appsettings.json && dotnet JT.CertificateReader.Web.dll"
secrets:
appsettings:
file: ./appsettings.Production.json
The container exposes the following ports:
| Variable | Description | Default | Example |
|---|---|---|---|
ASPNETCORE_ENVIRONMENT | Application environment | Production | Development, Staging, Production |
ASPNETCORE_URLS | URLs the app listens on | http://+:9080 | http://+:9080;http://+:9081 |
Logging__LogLevel__Default | Default logging level | Information | Debug, Information, Warning |
Logging__LogLevel__Microsoft.AspNetCore | ASP.NET Core logging | Warning | Information, Warning, Error |
ReverseProxy__EnableForwardedHeaders | Enable forwarded headers | true | true, false |
ReverseProxy__SslTerminatedAtProxy | SSL terminated at proxy | false | true (set when behind Nginx with SSL) |
ReverseProxy__TrustForwardedProto | Trust X-Forwarded-Proto | true | true, false |
ReverseProxy__ForwardLimit | Max proxy hops to trust | 1 | 1, 2, 3 |
AllowedHosts | Allowed host headers | * | localhost;yourdomain.com |
The application is designed to work seamlessly behind reverse proxies like Nginx, Traefik, or Apache.
appsettings.json)You can mount a custom appsettings.json to configure reverse proxy settings:
docker run -d \
-p 8080:9080 \
-v $(pwd)/appsettings.json:/app/appsettings.json:ro \
jtenorio/certificate-reader:latest
appsettings.json for Reverse Proxy{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "localhost;yourdomain.com;*.yourdomain.com",
"ReverseProxy": {
"EnableForwardedHeaders": true,
"ForwardLimit": 1,
"KnownProxies": [],
"KnownNetworks": [],
"PreserveHostHeader": false,
"AllowedProxyHosts": [],
"EnableDebugLogging": false,
"SslTerminatedAtProxy": true,
"TrustForwardedProto": true
}
}
server {
listen 443 ssl http2;
server_name yourdomain.com;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
location / {
proxy_pass http://certificate-reader:9080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
}
}
version: '3.8'
services:
certificate-reader:
image: jtenorio/certificate-reader:latest
labels:
- "traefik.enable=true"
- "traefik.http.routers.cert-reader.rule=Host(`yourdomain.com`)"
- "traefik.http.routers.cert-reader.entrypoints=websecure"
- "traefik.http.routers.cert-reader.tls=true"
- "traefik.http.routers.cert-reader.tls.certresolver=letsencrypt"
- "traefik.http.services.cert-reader.loadbalancer.server.port=9080"
networks:
- traefik
networks:
traefik:
external: true
GET / - Main upload and generation interfaceGET /health - Health check endpointGET /ready - Kubernetes readiness probe endpointPOST /api/CertificateApi/generate
Content-Type: application/json
{
"certificateName": "MyTestCert",
"password": "SecureP@ssw0rd!"
}
POST /api/CertificateApi/process
Content-Type: multipart/form-data
--boundary
Content-Disposition: form-data; name="certificate"; filename="cert.pfx"
Content-Type: application/x-pkcs12
[binary data]
--boundary
Content-Disposition: form-data; name="password"
YourPassword
--boundary--
POST /api/CertificateApi/export-public-key
Content-Type: multipart/form-data
[Similar to process endpoint]
POST /api/CertificateApi/export-private-key
Content-Type: multipart/form-data
[Similar to process endpoint]
POST /api/CertificateApi/export-jwk
Content-Type: multipart/form-data
[Similar to process endpoint]
The application provides health check endpoints for load balancers and orchestrators:
# Basic health check
curl http://localhost:9080/health
# Kubernetes readiness probe
curl http://localhost:9080/ready
apiVersion: apps/v1
kind: Deployment
metadata:
name: certificate-reader
spec:
replicas: 2
selector:
matchLabels:
app: certificate-reader
template:
metadata:
labels:
app: certificate-reader
spec:
containers:
- name: certificate-reader
image: jtenorio/certificate-reader:latest
ports:
- containerPort: 9080
name: http
livenessProbe:
httpGet:
path: /health
port: 9080
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /ready
port: 9080
initialDelaySeconds: 10
periodSeconds: 5
resources:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "256Mi"
cpu: "500m"
---
apiVersion: v1
kind: Service
metadata:
name: certificate-reader
spec:
selector:
app: certificate-reader
ports:
- port: 80
targetPort: 9080
type: ClusterIP
docker run -d \
-v $(pwd)/appsettings.json:/app/appsettings.json:ro \
jtenorio/certificate-reader:latest
docker run -d \
-v $(pwd)/logs:/app/logs \
jtenorio/certificate-reader:latest
# Check logs
docker logs certificate-reader
# Verify port availability
netstat -an | grep 9080
# Test from inside the container
docker exec certificate-reader wget -O- http://localhost:9080/health
# Check firewall rules
# Verify port mapping
docker ps
# Clone the repository
git clone https://github.com/jtenoriodseldon/certificatereader.git
# Build the Docker image
docker build -t certificate-reader:latest -f JT.CertificateReader.Web/Dockerfile .
# Note: Requires GitHub Personal Access Token for private NuGet package
docker build --build-arg GITHUB_TOKEN=your_token -t certificate-reader:latest -f JT.CertificateReader.Web/Dockerfile .
See the repository for license information.
ā ļø Important: This application does NOT store any certificates. All processing is done in-memory and certificates are discarded immediately after processing. However, when deploying publicly, ensure you:
latest - Latest stable version.NET, ASP.NET Core, Certificate, X.509, JWK, Cryptography, Security, Alpine LinuxMade with ā¤ļø by Darth Seldon
Content type
Image
Digest
sha256:6c40227e7ā¦
Size
55.7 MB
Last updated
11 months ago
docker pull jtenorio/certificate-reader