ssl — SSL/TLS-modul¶
Denna modul ger tillgång till funktioner för kryptering enligt Transport Layer Security (tidigare och allmänt känt som ”Secure Sockets Layer”) samt motpartsautentisering för nätverkssocketar, både på klient- och serversidan.
Tips
Ny på TLS på kameran? Börja med handledningen Arbeta med TLS-certifikat. Den går igenom hur du väljer nyckeltyper, skapar och konverterar certifikat till det DER-format som kameran kräver, får över dem till enheten samt verifierar servrar och klienter – med kompletta fungerande exempel.
Anteckning
MicroPython implementerar inte ssl.SSLError. Fel i SSL/TLS rapporteras i stället som OSError.
Exempel¶
TLS-klient som verifierar serverns certifikat mot ett CA-certifikat (i DER-format) som lagras i filsystemet:
import socket
import ssl
import ntptime
# CERT_REQUIRED checks the certificate's validity dates, so the clock
# must be set (see the certificates tutorial linked above).
ntptime.settime()
# Open a plain TCP connection.
addr = socket.getaddrinfo("example.com", 443)[0][-1]
sock = socket.socket()
sock.connect(addr)
# Wrap it for TLS and require a valid certificate.
ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
ctx.verify_mode = ssl.CERT_REQUIRED
ctx.load_verify_locations(cafile="ca.der")
ssock = ctx.wrap_socket(sock, server_hostname="example.com")
ssock.write(b"GET / HTTP/1.0\r\nHost: example.com\r\n\r\n")
print(ssock.read())
ssock.close()
För en snabb, osäker anslutning (utan certifikatvalidering) kan bekvämlighetsfunktionen ssl.wrap_socket() användas i stället:
ssock = ssl.wrap_socket(sock, server_hostname="example.com")
TLS-server som presenterar sitt eget certifikat och sin privata nyckel (DER-format):
import socket
import ssl
sock = socket.socket()
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind(socket.getaddrinfo("0.0.0.0", 8443)[0][-1])
sock.listen(1)
ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
ctx.load_cert_chain("server.der", "server.key")
while True:
client, addr = sock.accept()
sclient = ctx.wrap_socket(client, server_side=True)
sclient.write(b"hello\n")
sclient.close()
Funktioner¶
- ssl.wrap_socket(sock: Any, server_side: bool = False, key: bytes | None = None, cert: bytes | None = None, cert_reqs: int = CERT_NONE, cadata: bytes | None = None, server_hostname: str | None = None, do_handshake: bool = True) Any¶
Omslut den angivna sock och returnera ett nytt omslutet socket-objekt. Implementationen av denna funktion är att först skapa en
SSLContextoch sedan anropa metodenSSLContext.wrap_socket()på det kontextobjektet. Argumenten sock, server_side och server_hostname skickas oförändrade vidare till metodanropet. Argumentet do_handshake skickas vidare som do_handshake_on_connect. De återstående argumenten har följande beteende:cert_reqs avgör om motparten (server eller klient) måste presentera ett giltigt certifikat. Observera att
ssl.CERT_NONEochssl.CERT_OPTIONALinte validerar något certifikat; endastssl.CERT_REQUIREDgör det.cadata är ett bytes-objekt som innehåller CA-certifikatkedjan (i DER-format) som ska validera motpartens certifikat. För närvarande stöds endast ett enda DER-kodat certifikat.
Klasser¶
- class ssl.SSLContext(protocol: int, /)¶
Skapa en ny SSLContext-instans. Argumentet protocol måste vara en av konstanterna
PROTOCOL_*.- load_cert_chain(certfile: str | bytes, keyfile: str | bytes) None¶
Läs in en privat nyckel och motsvarande certifikat. certfile är en sträng med filsökvägen till certifikatet. keyfile är en sträng med filsökvägen till den privata nyckeln.
Skillnad mot CPython
MicroPython-tillägg: certfile och keyfile kan vara bytes-objekt i stället för strängar, i vilket fall de tolkas som själva certifikat-/nyckeldatan.
- load_verify_locations(cafile: str | None = None, cadata: bytes | None = None) None¶
Läs in CA-certifikatkedjan som ska validera motpartens certifikat. cafile är filsökvägen till CA-certifikaten. cadata är ett bytes-objekt som innehåller CA-certifikaten. Endast ett av dessa argument bör anges.
- get_ciphers() List[str]¶
Hämta en lista över aktiverade chiffer, returnerad som en lista med strängar.
- set_ciphers(ciphers: List[str]) None¶
Ange de tillgängliga chiffren för socketar som skapas med denna kontext. ciphers bör vara en lista med strängar i IANA:s chiffersvitformat .
- wrap_socket(sock: Any, *, server_side: bool = False, do_handshake_on_connect: bool = True, server_hostname: str | None = None, client_id: bytes | None = None) Any¶
Tar en stream sock (vanligtvis en socket.socket-instans av typen
SOCK_STREAM) och returnerar en instans av ssl.SSLSocket som omsluter den underliggande strömmen. Det returnerade objektet har de vanliga gränssnittsmetoderna för stream, såsomread(),write()osv.server_side väljer om den omslutna socketen befinner sig på server- eller klientsidan. En SSL-socket på serversidan bör skapas från en vanlig socket som returneras av
accept()på en icke-SSL-lyssnande serversocket.do_handshake_on_connect avgör om handskakningen görs som en del av
wrap_socketeller om den skjuts upp för att utföras som en del av de första läsningarna eller skrivningarna. För blockerande socketar är det standard att utföra handskakningen omedelbart. För icke-blockerande socketar (dvs. när den sock som skickas in iwrap_socketär i icke-blockerande läge) bör handskakningen i allmänhet skjutas upp eftersomwrap_socketannars blockerar tills den slutförs.server_hostname är avsett att användas som klient och anger värdnamnet att kontrollera mot det mottagna servercertifikatet. Det anger även namnet för Server Name Indication (SNI), vilket gör att servern kan presentera rätt certifikat.
client_id är ett MicroPython-specifikt tilläggsargument som endast används vid implementering av en DTLS-server. Se DTLS-stöd för detaljer.
Varning
Som standard utförs ingen certifikatvalidering (
ssl.CERT_NONE). För en säker anslutning måste du verifiera motpartens certifikat genom att sätta cert_reqs /SSLContext.verify_modetillssl.CERT_REQUIRED; annars är anslutningen sårbar för man-in-the-middle-attacker.CPythons
wrap_socketreturnerar ettSSLSocket-objekt som har metoder typiska för socketar, såsomsend,recvosv. MicroPythonswrap_socketreturnerar ett objekt som mer liknar CPythonsSSLObject, vilket inte har dessa socket-metoder.
- verify_mode¶
Ange eller hämta beteendet för verifiering av motpartens certifikat. Måste vara en av konstanterna
CERT_*.Anteckning
ssl.CERT_REQUIREDkräver att enhetens datum/tid är korrekt inställd, t.ex. med mpremote rtc --set ellerntptime, ochserver_hostnamemåste anges när man är på klientsidan.
DTLS-stöd¶
Skillnad mot CPython
Detta är ett MicroPython-tillägg.
Denna modul stöder DTLS i klient- och serverläge via konstanterna PROTOCOL_DTLS_CLIENT och PROTOCOL_DTLS_SERVER som kan användas som argumentet protocol till SSLContext.
I detta fall förväntas den underliggande socketen bete sig som en datagramsocket (dvs. som den socket som öppnas med socket.socket med socket.AF_INET som af och socket.SOCK_DGRAM som type).
Stöd för DTLS-server¶
MicroPythons stöd för DTLS-server är konfigurerat med ”Hello Verify” enligt kravet för DTLS 1.2. Detta är transparent för DTLS-klienter, men det finns relevanta överväganden vid implementering av en DTLS-server i MicroPython:
Servern bör skicka ett extra argument client_id vid anrop av
SSLContext.wrap_socket(). Detta ID måste vara ettbytes-objekt (eller liknande) med en transportspecifik identifierare som representerar klienten.Den enklaste metoden är att konvertera tuppeln
(client_ip, client_port)som returneras avsocket.recv_from()till en byte-sträng, dvs.:_, client_addr = sock.recvfrom(1, socket.MSG_PEEK) sock.connect(client_addr) # Connect back to the client sock = ssl_ctx.wrap_socket(sock, server_side=True, client_id=repr(client_addr).encode())
Första gången en klient ansluter kommer serverns anrop till
wrap_socketatt misslyckas med ettOSError-fel ”Hello Verify Required”. Detta beror på att DTLS-kakan ”Hello Verify” ännu inte är känd av klienten. Om samma klient ansluter en andra gång kommerwrap_socketatt lyckas.DTLS-kakor för ”Hello Verify” är kopplade till
SSLContext-objektet, så sammaSSLContext-objekt bör användas för att omsluta en efterföljande anslutning från samma klient. Kakimplementationen inkluderar en timeout och har konstant minnesanvändning oavsett hur många klienter som ansluter, så det går bra att återanvända sammaSSLContext-objekt under serverns livstid.
Konstanter¶
- ssl.CERT_NONE: int¶
Stödd värde för parametern cert_reqs och attributet
SSLContext.verify_mode. Ingen certifikatverifiering utförs på motparten.
- ssl.CERT_OPTIONAL: int¶
Stödd värde för parametern cert_reqs och attributet
SSLContext.verify_mode. Certifikatverifiering är valfri. Observera att detta på OpenMV Cam beter sig somssl.CERT_NONE.
- ssl.CERT_REQUIRED: int¶
Stödd värde för parametern cert_reqs och attributet
SSLContext.verify_mode. Ett giltigt certifikat krävs från motparten.