Modifica: dopo qualche sforzo, I ha re-implementato una libreria SSL efficiente in RAM, che può essere eseguita nel tipo di RAM indicato di seguito. Ha molte più funzionalità e flessibilità delle mie precedenti creazioni, eppure è ancora molto piccolo. Ancora più importante, è anche opensource (licenza MIT). Divertiti: link
È possibile implementare un client SSL / TLS (o server) in circa 21 kB di codice ARM (pollice), che richiede meno di 20 kB di RAM durante l'esecuzione (*). So che si può fare perché l'ho fatto (mi dispiace, non open source). La maggior parte della complessità di TLS deriva dal supporto di molti tipi di algoritmi crittografici, negoziati durante l'iniziale stretta di mano; se ti concentri solo su un set di algoritmi crittografici, puoi ridurre il codice a qualcosa di abbastanza piccolo. Ti consiglio di utilizzare TLS 1.2 con la suite di crittografia TLS_RSA_WITH_AES_128_CBC_SHA256
: per quello, avrai solo bisogno di implementazioni per RSA, AES e SHA-256 (per TLS 1.1 e precedenti, occorrerebbero anche implementazioni per MD5 e SHA-1, che non è difficile ma impiegheranno alcuni kByte di codice in più). Inoltre, puoi renderlo sincrono (in chiaro TLS, client e server possono parlare simultaneamente, ma nulla li costringe a farlo) e omettere la parte "rinegoziazione handshake" (client e server eseguono una stretta di mano iniziale , ma possono rifarlo in seguito durante la connessione).
La parte più difficile nell'implementazione del protocollo riguarda i certificati. Il server e il client si autenticano a vicenda utilizzando le rispettive chiavi private - con RSA, il server esegue una decodifica RSA, mentre il client calcola una firma RSA. Ciò fornisce l'autenticazione fintanto che client e server si conoscono a vicenda le chiavi pubbliche; quindi, mandano le loro chiavi pubbliche l'una all'altra, racchiuse in certificati che sono blob firmati. Un certificato deve essere convalidato prima dell'uso, vale a dire la sua firma verificata rispetto a una chiave pubblica conosciuta a priori (spesso chiamata "root CA" o "trust anchor"). Il client non può usare ciecamente la chiave pubblica che il server ha appena inviato, perché consentirebbe attacchi man-in-the-middle.
L'analisi e la convalida del certificato X.509 è un po 'complessa (nella mia implementazione, era 6 kB di codice, fuori dai 21 kB). A seconda della configurazione, potresti avere opzioni più leggere; ad esempio, se si riesce a codificare la chiave pubblica del server nel client, il client può semplicemente usare quella chiave e gettare via il certificato del server, che è "solo un blob": nessuna necessità di analisi, nessuna certificazione, protocollo molto robusto. Si potrebbe anche definire il proprio formato "certificato". Un'altra possibilità è quella di utilizzare SRP , che è un meccanismo di scambio chiave in cui entrambe le parti si autenticano a vicenda per quanto riguarda la conoscenza di un valore segreto condiviso (la magia di SRP è che è solida anche se il segreto condiviso ha un'entropia relativamente bassa, ad esempio una password); usa TLS_SRP_SHA_WITH_AES_128_CBC_SHA
.
Il punto qui è che, anche con un protocollo personalizzato, non si otterrà qualcosa di veramente più leggero di un TLS ridotto, almeno se si vuole mantenerlo robusto. E progettare un protocollo robusto non è affatto affatto ; La TLS arrivò al punto di essere considerata sufficientemente sicura attraverso anni di sangue e lacrime. Quindi è molto meglio riusare TLS che inventare il proprio protocollo. Inoltre, questo rende il codice molto più facile da testare (puoi interagire con le implementazioni SSL / TLS esistenti).
(*) Fuori dai 20 kB di RAM, c'è un buffer da 16,5 kB per i "record" in entrata, perché TLS afferma che i record possono raggiungere quella dimensione. Se si controlla sia il codice client che quello server, è possibile organizzare una dimensione massima record inferiore, risparmiando così sui requisiti di RAM. L'overhead per record non è molto meno di 50 byte in media, quindi è possibile utilizzare i record di 4 kB e avere comunque comunicazioni efficienti.