82 lines
2.9 KiB
Python
82 lines
2.9 KiB
Python
from flask import Flask, request, render_template_string, redirect, url_for
|
|
from cryptography import x509
|
|
from cryptography.hazmat.backends import default_backend
|
|
|
|
app = Flask(__name__)
|
|
|
|
# Simple HTML Form
|
|
HTML_TEMPLATE = """
|
|
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<meta name="description" content="An online tool to decode SSL/TLS certificates. Paste your PEM certificate and instantly view details like Common Name (CN), Subject Alternative Names (SANs), issuer, validity, and more.">
|
|
<meta name="keywords" content="SSL certificate decoder, PEM decoder, SAN lookup, CN extractor, TLS cert info, certificate parser, online SSL tool">
|
|
<meta name="author" content="Your Name or Company">
|
|
<meta name="robots" content="index, follow">
|
|
|
|
<title>SSL Certificate Decoder - View CN, SAN, Issuer & More</title>
|
|
</head>
|
|
<body>
|
|
<h2>Decode SSL Certificate</h2>
|
|
<form method="POST">
|
|
<textarea name="certificate" rows="20" cols="80" placeholder="Paste your PEM certificate here..."></textarea><br><br>
|
|
<input type="submit" value="Decode">
|
|
</form>
|
|
|
|
{% if cert_info %}
|
|
<h3>Certificate Information:</h3>
|
|
<pre>{{ cert_info }}</pre>
|
|
{% endif %}
|
|
</body>
|
|
</html>
|
|
"""
|
|
|
|
def parse_certificate(pem_data):
|
|
try:
|
|
cert = x509.load_pem_x509_certificate(pem_data.encode(), default_backend())
|
|
except Exception as e:
|
|
return f"Invalid certificate: {e}"
|
|
|
|
issuer = cert.issuer.get_attributes_for_oid(x509.OID_COMMON_NAME)
|
|
subject = cert.subject.get_attributes_for_oid(x509.OID_COMMON_NAME)
|
|
not_before = cert.not_valid_before
|
|
not_after = cert.not_valid_after
|
|
serial_number = cert.serial_number
|
|
sig_algo = cert.signature_hash_algorithm.name
|
|
|
|
# Get SANs
|
|
try:
|
|
ext = cert.extensions.get_extension_for_class(x509.SubjectAlternativeName)
|
|
sans = ext.value.get_values_for_type(x509.DNSName)
|
|
except x509.ExtensionNotFound:
|
|
sans = []
|
|
|
|
output = f"""
|
|
Subject CN: {subject[0].value if subject else 'N/A'}
|
|
Issuer CN: {issuer[0].value if issuer else 'N/A'}
|
|
Valid From: {not_before}
|
|
Valid Until: {not_after}
|
|
Serial Number: {serial_number}
|
|
Signature Alg: {sig_algo}
|
|
SANs: {', '.join(sans) if sans else 'None'}
|
|
"""
|
|
return output.strip()
|
|
|
|
@app.route("/", methods=["GET", "POST"])
|
|
def index():
|
|
if request.method == "POST":
|
|
pem_cert = request.form.get("certificate", "").strip()
|
|
cert_info = parse_certificate(pem_cert)
|
|
# Store result temporarily in session or pass via GET param
|
|
return redirect(url_for('index', cert_info=cert_info))
|
|
|
|
# GET Request — show result if available
|
|
cert_info = request.args.get('cert_info')
|
|
return render_template_string(HTML_TEMPLATE, cert_info=cert_info)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
app.run(debug=True, port=5000, host='0.0.0.0')
|