14.4.3. Kendinden imzalı sertifikalar#
Kendinden imzalı bir sertifika, kontrol ettiğiniz iki cihaz arasında TLS’i çalıştırmanın en hızlı yoludur: her iki uç da kendiniz oluşturduğunuz tek bir sertifikaya güvenir. Bağlantının her iki tarafını da yapılandırdığınız her dağıtımı kapsar – herkese açık bir Sertifika Yetkilisi (CA), yalnızca üçüncü taraf istemcilerin özel bir sertifikaya güvenmeleri söylenmeden bağlanması gerektiğinde devreye girer.
14.4.3.1. Kendinden imzalı bir sertifika oluşturma#
OpenSSL’i geliştirme makinenizde çalıştırın. subjectAltName (SAN), modern TLS istemcilerinin ana bilgisayar adı doğrulaması sırasında kontrol ettiği şeydir, bu nedenle bunu istemcilerin kameraya erişmek için kullanacağı ana bilgisayar adlarına ve/veya IP adreslerine ayarlayın (CN tek başına eskidir ve birçok istemci tarafından yok sayılır). DNS:openmv / IP:192.168.1.50 değerini istemcilerinizin gerçekten bağlandığı adresle değiştirin.
ECDSA P-256 – önerilen:
# Generate a P-256 private key.
openssl ecparam -name prime256v1 -genkey -noout -out server.key
# Self-signed certificate valid for one year, with a SAN.
openssl req -new -x509 -key server.key -out server.crt -days 365 \
-subj "/CN=openmv" -addext "subjectAltName=DNS:openmv,IP:192.168.1.50"
ECDSA P-384 – daha güçlü, daha büyük/daha yavaş:
openssl ecparam -name secp384r1 -genkey -noout -out server.key
openssl req -new -x509 -key server.key -out server.crt -days 365 \
-subj "/CN=openmv" -addext "subjectAltName=DNS:openmv,IP:192.168.1.50"
RSA-2048 – maksimum uyumluluk:
openssl req -new -x509 -newkey rsa:2048 -nodes -keyout server.key \
-out server.crt -days 365 -subj "/CN=openmv" \
-addext "subjectAltName=DNS:openmv,IP:192.168.1.50"
Not
Bir istemci sertifikası (aşağıda karşılıklı kimlik doğrulama için kullanılır) tam olarak bu aynı komutlarla oluşturulur – sertifikanın kendisinde istemciye özgü hiçbir şey yoktur. Sadece farklı adlar altında ikinci, bağımsız bir anahtar/sertifika çifti oluşturun (örn. client.key / client.crt) ve bunu mTLS örneğinde gösterildiği gibi istemcide kullanın. subjectAltName yalnızca eşin ana bilgisayar adını doğruladığı taraf için önemlidir (istemci, sunucunun adını kontrol eder; hiçbir şey istemcinin adını kontrol etmez), bu nedenle yalnızca istemci sertifikası için atlanabilir. -subj / CN aynı şekilde bir istemci sertifikasında yalnızca bir etikettir – buradaki sunucu tarafı yalnızca sertifikanın güvenilen bir CA’ya zincirlenip zincirlenmediğini kontrol eder, adı asla eşleştirmez – bu nedenle bunu o istemciyi tanımlayan herhangi bir şeye ayarlayın (örn. /CN=sensor-01). Yine de bir -subj değeri tutun ki OpenSSL sertifikayı etkileşimsiz olarak oluşturabilsin.
Sertifika ömrü -days ile ayarlanır; sertifikaların süresi dolar ve bu süreden önce yeniden oluşturulup yeniden dağıtılmaları gerekir.
14.4.3.2. DER’e dönüştürme#
Hem sertifikayı hem de özel anahtarı kameraya kopyalamadan önce DER’e dönüştürün:
openssl x509 -in server.crt -outform DER -out server.der
openssl pkey -in server.key -outform DER -out server.key.der
14.4.3.3. Dosyaları kameraya kopyalama#
DER dosyalarını kameranın dosya sistemine kopyalayın – örneğin onları OpenMV Cam’in USB sürücüsüne sürükleyerek veya mpremote cp server.der : ve mpremote cp server.key.der : ile. Doğrulama yapan tarafta, CA / eş sertifikasını da DER biçiminde kopyalayın.
DER dosyalarının yazılabilir dosya sisteminde bulunması gerekmez. MicroPython, salt okunur bir ROMFS imajını da /rom konumuna bağlayabilir ve oraya yerleştirilen sertifikalar tıpkı diğer dosyalar gibi yüklenir – örn. ctx.load_cert_chain("/rom/server.der", "/rom/server.key.der"). Bir ROMFS imajı geliştirme makinenizde hazırlanır ve çalışma zamanında salt okunurdur, bu nedenle sertifika cihaz üzerinde değiştirilemez – bir üretim birimini kilitlemek için kullanışlıdır. ROMFS içinde saklanan bir özel anahtarın hâlâ kamerada çalışan kod tarafından okunabilir olduğunu unutmayın; ROMFS çıkarmaya değil, değiştirmeye karşı koruma sağlar. ROMFS’te yerleşik bir sertifika yalnızca imajın yeniden derlenmesi ve yeniden flash’lanmasıyla değiştirilebilir.
14.4.3.4. Sertifikanın kullanılması#
Saati ayarlayan, bir soket açan, kendinden imzalı bir sunucuyu doğrulayan ve veri alışverişi yapan eksiksiz bir istemci
import socket
import ssl
import ntptime
ntptime.settime() # correct clock for the validity check
# Open a plain TCP connection.
addr = socket.getaddrinfo("openmv", 8443)[0][-1]
sock = socket.socket()
sock.connect(addr)
# Wrap it for TLS, trusting the server's self-signed certificate.
ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
ctx.verify_mode = ssl.CERT_REQUIRED
ctx.load_verify_locations(cafile="server.der")
ssock = ctx.wrap_socket(sock, server_hostname="openmv")
ssock.write(b"hello\n")
print(ssock.read())
ssock.close()
Sertifikasını ve anahtarını sunan eksiksiz bir sunucu
import socket
import ssl
import ntptime
ntptime.settime() # correct clock for the validity check
ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
ctx.load_cert_chain("server.der", "server.key.der")
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)
while True:
client, addr = sock.accept()
sclient = ctx.wrap_socket(client, server_side=True)
sclient.write(b"hello\n")
print(sclient.read())
sclient.close()
Karşılıklı kimlik doğrulama (mTLS) için sunucu ek olarak bir istemci sertifikası ister ve doğrular, istemci de kendine ait bir sertifika sunar:
# Server side: also demand and verify a client certificate.
ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
ctx.load_cert_chain("server.der", "server.key.der")
ctx.verify_mode = ssl.CERT_REQUIRED
ctx.load_verify_locations(cafile="client.der")
# Client side: present a certificate of our own.
ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
ctx.load_cert_chain("client.der", "client.key.der")
ctx.verify_mode = ssl.CERT_REQUIRED
ctx.load_verify_locations(cafile="server.der")
Tam API için ssl modülü belgelerine bakın.
Not
Bu sayfadaki her şey DTLS (UDP üzerinden TLS) için değişmeden geçerlidir. Anahtarlar, sertifikalar, DER biçimi, güven modeli, sona erme endişeleri ve load_cert_chain / load_verify_locations çağrıları aynıdır; yalnızca aktarım katmanı farklıdır – TLS protokol sabitleri yerine bir socket.SOCK_DGRAM soketini sarmalar ve ssl.PROTOCOL_DTLS_CLIENT / ssl.PROTOCOL_DTLS_SERVER seçersiniz. Tek ekstra ayrıntı, sunucu tarafında bir kimlik sahteciliği önleme çerezidir – yeni bir istemciden gelen ilk bağlantının başarısız olması beklenir ve istemci yalnızca yeniden dener; ayrıntılar için DTLS desteği bölümüne bakın.