import socket import ssl from datetime import datetime, timezone from cryptography import x509 from cryptography.hazmat.primitives import serialization def ssl_info(hostname, port=443): # Inisialisasi variabel status keamanan code = 0 # OK message = "OK" cert_der = None # --- LANGKAH 1: Uji Validitas SSL (Deteksi Error) --- standard_context = ssl.create_default_context() try: with socket.create_connection((hostname, port), timeout=5) as sock: with standard_context.wrap_socket( sock, server_hostname=hostname) as ssock: cert_der = ssock.getpeercert(binary_form=True) except ssl.SSLCertVerificationError as e: code = e.errno # 1 message = e.reason except socket.gaierror as e: code = e.errno # -2 message = e.strerror if code not in (0, 1): return dict(code=code, message=message) # --- LANGKAH 2: Ambil Data Secara Paksa Jika Terjadi Error --- if code == 1: # Buat konteks longgar tanpa verifikasi keamanan untuk mengunduh # sertifikat bermasalah bypass_context = ssl.create_default_context() bypass_context.check_hostname = False bypass_context.verify_mode = ssl.CERT_NONE with socket.create_connection((hostname, port), timeout=5) as sock: with bypass_context.wrap_socket( sock, server_hostname=hostname) as ssock: cert_der = ssock.getpeercert(binary_form=True) # --- LANGKAH 3: Parse Data Sertifikat Memakai Cryptography --- cert = x509.load_der_x509_certificate(cert_der) # A. Ekstrak Penerbit (Issuer) issuer_orgs = cert.issuer.get_attributes_for_oid( x509.oid.NameOID.ORGANIZATION_NAME) if not issuer_orgs: issuer_orgs = cert.issuer.get_attributes_for_oid( x509.oid.NameOID.COMMON_NAME) issuer_name = issuer_orgs[0].value if issuer_orgs else "Tidak Diketahui" # B. Ekstrak Tanggal Kedaluwarsa expiry_date = cert.not_valid_after_utc days_left = (expiry_date - datetime.now(timezone.utc)).days if days_left < 0: code = 2 message = f'Kedaluwarsa {abs(days_left)} hari yang lalu' # C. Ekstrak Public Key (Format PEM) public_key = cert.public_key() pem_public_key = public_key.public_bytes( encoding=serialization.Encoding.PEM, format=serialization.PublicFormat.SubjectPublicKeyInfo ).decode('utf-8') return dict( code=code, message=message, issuer=issuer_name, expiry_date=expiry_date, days_left=days_left, public_key=pem_public_key) if __name__ == "__main__": import sys from pprint import pprint hostname = sys.argv[1] r = ssl_info(hostname) pprint(r)