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.