ssl — SSL/TLS modülü¶
Bu modül, hem istemci hem de sunucu tarafında ağ soketleri için Transport Layer Security (önceden ve yaygın olarak “Secure Sockets Layer” olarak bilinen) şifreleme ve karşı taraf kimlik doğrulama olanaklarına erişim sağlar.
Tüyo
Kamerada TLS konusunda yeni misiniz? TLS sertifikalarıyla çalışma öğreticisiyle başlayın. Bu öğretici; anahtar türlerini seçmeyi, sertifikaları oluşturmayı ve kameranın gerektirdiği DER biçimine dönüştürmeyi, bunları cihaza aktarmayı ve sunucularla istemcileri doğrulamayı tam çalışan örneklerle adım adım anlatır.
Not
MicroPython ssl.SSLError öğesini uygulamaz. SSL/TLS hataları bunun yerine OSError olarak yükseltilir.
Örnekler¶
Sunucunun sertifikasını, dosya sisteminde saklanan (DER biçimindeki) bir CA sertifikasıyla doğrulayan TLS istemcisi:
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()
Hızlı ve güvensiz bir bağlantı için (sertifika doğrulaması olmadan) bunun yerine ssl.wrap_socket() kolaylık işlevi kullanılabilir:
ssock = ssl.wrap_socket(sock, server_hostname="example.com")
Kendi sertifikasını ve özel anahtarını (DER biçimi) sunan TLS sunucusu:
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()
İşlevler¶
- 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¶
Verilen sock öğesini sarmalar ve yeni bir sarmalanmış soket nesnesi döndürür. Bu işlevin uygulanışı, önce bir
SSLContextoluşturmak ve ardından o bağlam nesnesi üzerindeSSLContext.wrap_socket()yöntemini çağırmaktır. sock, server_side ve server_hostname argümanları yöntem çağrısına değiştirilmeden aktarılır. do_handshake argümanı do_handshake_on_connect olarak aktarılır. Kalan argümanlar şu davranışa sahiptir:cert_reqs, karşı tarafın (sunucu veya istemci) geçerli bir sertifika sunması gerekip gerekmediğini belirler.
ssl.CERT_NONEvessl.CERT_OPTIONALöğelerinin hiçbir sertifikayı doğrulamadığını; yalnızcassl.CERT_REQUIREDöğesinin doğruladığını unutmayın.cadata, karşı tarafın sertifikasını doğrulayacak CA sertifika zincirini (DER biçiminde) içeren bir bytes nesnesidir. Şu anda yalnızca tek bir DER kodlu sertifika desteklenmektedir.
Sınıflar¶
- class ssl.SSLContext(protocol: int, /)¶
Yeni bir SSLContext örneği oluşturur. protocol argümanı
PROTOCOL_*sabitlerinden biri olmalıdır.- load_cert_chain(certfile: str | bytes, keyfile: str | bytes) None¶
Bir özel anahtarı ve ona karşılık gelen sertifikayı yükler. certfile, sertifikanın dosya yolunu içeren bir dizgedir. keyfile, özel anahtarın dosya yolunu içeren bir dizgedir.
CPython’dan Farkı
MicroPython eklentisi: certfile ve keyfile, dizge yerine bytes nesneleri olabilir; bu durumda gerçek sertifika/anahtar verisi olarak yorumlanırlar.
- load_verify_locations(cafile: str | None = None, cadata: bytes | None = None) None¶
Karşı tarafın sertifikasını doğrulayacak CA sertifika zincirini yükler. cafile, CA sertifikalarının dosya yoludur. cadata, CA sertifikalarını içeren bir bytes nesnesidir. Bu argümanlardan yalnızca biri sağlanmalıdır.
- get_ciphers() List[str]¶
Etkin şifrelerin bir listesini, dizgelerden oluşan bir liste olarak döndürür.
- set_ciphers(ciphers: List[str]) None¶
Bu bağlamla oluşturulan soketler için kullanılabilir şifreleri ayarlar. ciphers, IANA cipher suite biçiminde dizgelerden oluşan bir liste olmalıdır.
- 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¶
Bir stream sock (genellikle
SOCK_STREAMtüründe bir socket.socket örneği) alır ve alttaki akışı sarmalayan bir ssl.SSLSocket örneği döndürür. Döndürülen nesne,read(),write()gibi olağan stream arayüz yöntemlerine sahiptir.server_side, sarmalanan soketin sunucu tarafında mı yoksa istemci tarafında mı olduğunu seçer. Sunucu tarafı bir SSL soketi, SSL olmayan bir dinleyici sunucu soketi üzerinde
accept()çağrısından döndürülen normal bir soketten oluşturulmalıdır.do_handshake_on_connect, el sıkışmanın
wrap_socketişleminin bir parçası olarak mı yapılacağını yoksa ilk okuma veya yazmaların bir parçası olarak yapılmak üzere ertelenip ertelenmeyeceğini belirler. Bloklayan soketler için el sıkışmayı hemen yapmak standarttır. Bloklamayan soketler için (yaniwrap_socketöğesine aktarılan sock bloklamayan moddayken) el sıkışma genellikle ertelenmelidir, çünkü aksi takdirdewrap_sockettamamlanana kadar bloklar.server_hostname, istemci olarak kullanım içindir ve alınan sunucu sertifikasına karşı denetlenecek ana makine adını ayarlar. Ayrıca Server Name Indication (SNI) için adı belirler ve sunucunun uygun sertifikayı sunmasına olanak tanır.
client_id, yalnızca bir DTLS Sunucusu uygulanırken kullanılan, MicroPython’a özgü bir eklenti argümanıdır. Ayrıntılar için bkz. DTLS desteği.
Uyarı
Varsayılan olarak hiçbir sertifika doğrulaması yapılmaz (
ssl.CERT_NONE). Güvenli bir bağlantı için cert_reqs /SSLContext.verify_modeöğesinissl.CERT_REQUIREDolarak ayarlayarak karşı tarafın sertifikasını doğrulamanız gerekir; aksi takdirde bağlantı ortadaki adam (man-in-the-middle) saldırılarına karşı savunmasızdır.CPython’un
wrap_socketişlevi,send,recvgibi soketlere özgü yöntemlere sahip birSSLSocketnesnesi döndürür. MicroPython’unwrap_socketişlevi ise CPython’unSSLObjectöğesine daha benzer, bu soket yöntemlerine sahip olmayan bir nesne döndürür.
- verify_mode¶
Karşı taraf sertifikalarının doğrulanma davranışını ayarlar veya alır.
CERT_*sabitlerinden biri olmalıdır.Not
ssl.CERT_REQUIRED, cihazın tarih/saatinin doğru ayarlanmış olmasını gerektirir; örneğin mpremote rtc --set veyantptimekullanılarak. Ayrıca istemci tarafındaykenserver_hostnamebelirtilmelidir.
DTLS desteği¶
CPython’dan Farkı
Bu bir MicroPython eklentisidir.
Bu modül, SSLContext öğesinin protocol argümanı olarak kullanılabilen PROTOCOL_DTLS_CLIENT ve PROTOCOL_DTLS_SERVER sabitleri aracılığıyla istemci ve sunucu modunda DTLS’yi destekler.
Bu durumda alttaki soketin bir datagram soketi gibi davranması beklenir (yani af olarak socket.AF_INET ve type olarak socket.SOCK_DGRAM ile socket.socket kullanılarak açılan soket gibi).
DTLS sunucu desteği¶
MicroPython’un DTLS sunucu desteği, DTLS 1.2 için gerektiği gibi “Hello Verify” ile yapılandırılmıştır. Bu, DTLS istemcileri için saydamdır, ancak MicroPython’da bir DTLS sunucusu uygularken ilgili noktalar vardır:
Sunucu,
SSLContext.wrap_socket()çağırırken ek bir client_id argümanı geçmelidir. Bu kimlik, istemciyi temsil eden taşımaya özgü bir tanımlayıcı içeren birbytesnesnesi (veya benzeri) olmalıdır.En basit yaklaşım,
socket.recv_from()öğesinden döndürülen(client_ip, client_port)demetini bir bayt dizgesine dönüştürmektir; yani:_, 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())
Bir istemci ilk kez bağlandığında, sunucunun
wrap_socketçağrısı “Hello Verify Required” hatasıyla birOSErrorhatası vererek başarısız olur. Bunun nedeni, DTLS “Hello Verify” çerezinin istemci tarafından henüz bilinmemesidir. Aynı istemci ikinci kez bağlanırsawrap_socketbaşarılı olur.“Hello Verify” için DTLS çerezleri
SSLContextnesnesiyle ilişkilendirilir, bu nedenle aynı istemciden gelen sonraki bir bağlantıyı sarmalamak için aynıSSLContextnesnesi kullanılmalıdır. Çerez uygulaması bir zaman aşımı içerir ve kaç istemcinin bağlandığından bağımsız olarak sabit bellek kullanımına sahiptir, dolayısıyla aynıSSLContextnesnesini sunucunun ömrü boyunca yeniden kullanmak sorun değildir.
Sabitler¶
- ssl.PROTOCOL_TLS_CLIENT: int¶
TLS istemci modunu seçen, protocol parametresi için desteklenen değer.
- ssl.PROTOCOL_DTLS_CLIENT: int¶
DTLS istemci modunu seçen, protocol parametresi için desteklenen değer.
- ssl.PROTOCOL_DTLS_SERVER: int¶
DTLS sunucu modunu seçen, protocol parametresi için desteklenen değer.
- ssl.CERT_NONE: int¶
cert_reqs parametresi ve
SSLContext.verify_modeözniteliği için desteklenen değer. Karşı tarafta hiçbir sertifika doğrulaması yapılmaz.
- ssl.CERT_OPTIONAL: int¶
cert_reqs parametresi ve
SSLContext.verify_modeözniteliği için desteklenen değer. Sertifika doğrulaması isteğe bağlıdır. OpenMV Cam üzerinde bununssl.CERT_NONEgibi davrandığını unutmayın.
- ssl.CERT_REQUIRED: int¶
cert_reqs parametresi ve
SSLContext.verify_modeözniteliği için desteklenen değer. Karşı taraftan geçerli bir sertifika gereklidir.