1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
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)