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.