import asyncio import ssl from urllib.parse import urlparse async def analyze_crypto_handshake(url: str) -> float: parsed = urlparse(url) hostname = parsed.hostname or "" score = 0.0 # If traffic is plain http, let's briefly check if port 443 is wide open/preferred if parsed.scheme == 'http': try: # Quick async connection attempt to port 443 to check for HTTPS capability _, writer = await asyncio.wait_for( asyncio.open_connection(hostname, 443), timeout=0.050 ) writer.close() await writer.wait_closed() # If we successfully connected to 443, do not heavily penalize plain http # as it likely supports an immediate SSL upgrade/redirect. score += 0.1 except Exception: return 0.8 # No SSL listener on 443 at all? High risk. context = ssl.create_default_context() context.check_hostname = False context.verify_mode = ssl.CERT_NONE try: reader, writer = await asyncio.wait_for( asyncio.open_connection(hostname, 443, ssl=context), timeout=0.100 ) cipher_info = writer.get_extra_info('cipher') cert = writer.get_extra_info('peercert') writer.close() await writer.wait_closed() if cipher_info: _, tls_version, secret_bits = cipher_info if secret_bits < 128: score += 0.4 if tls_version in ['TLSv1', 'TLSv1.1']: score += 0.3 if not cert: score += 0.2 except Exception: if parsed.scheme == 'https': score += 0.7 # Hard failure on an explicit HTTPS request return min(score, 1.0)