import sys sys.unraisablehook = lambda unraisable: None import asyncio import ssl from argparse import ArgumentParser from aioquic.asyncio import connect from aioquic.quic.configuration import QuicConfiguration TLS13_CIPHERS = [ 'TLS_AES_128_GCM_SHA256', 'TLS_AES_256_GCM_SHA384', 'TLS_CHACHA20_POLY1305_SHA256', 'TLS_AES_128_CCM_SHA256' ] def get_client_supported_tls13_ciphers(): """Gibt die vom Client unterstützten TLS 1.3 Cipher-Suiten zurück.""" ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) supported = [] for cipher in ctx.get_ciphers(): if cipher['protocol'] == 'TLSv1.3' and cipher['name'] in TLS13_CIPHERS: supported.append(cipher['name']) return supported async def check_cipher(host, port, cipher): """Versucht eine QUIC-Verbindung mit der angegebenen Cipher-Suite herzustellen.""" config = QuicConfiguration(is_client=True) config.ciphers = [cipher] config.verify_mode = ssl.CERT_NONE config.alpn_protocols = ['h3'] # HTTP/3 ALPN try: async with asyncio.timeout(5): async with connect(host, port, configuration=config): return True except Exception: return False async def main(host, port): client_ciphers = get_client_supported_tls13_ciphers() supported_ciphers = [] for cipher in client_ciphers: if await check_cipher(host, port, cipher): supported_ciphers.append(cipher) for cipher in supported_ciphers: print(cipher) if __name__ == "__main__": parser = ArgumentParser(description="Ermittelt die unterstützten TLS 1.3 Cipher-Suiten eines HTTP/3-Servers.") parser.add_argument("host", help="Hostname des Servers") parser.add_argument("-p", "--port", type=int, default=443, help="Port des Servers (Standard: 443)") args = parser.parse_args() asyncio.run(main(args.host, args.port))