Per rispondere alla domanda su come impacchettare il testo cifrato e IV, la concatenazione dovrebbe essere sufficiente: IV || ciphertext || tag
. Questo formato è utile perché consente lo streaming di crittografia. Genera e invia l'IV, trasmetti in streaming la crittografia, quindi calcola e invia il tag di autenticazione (l'output di decrittografia non può essere trasmesso in streaming, tuttavia, come prima cosa deve essere controllato il tag).
Il lato negativo è che rende più difficile cambiare l'algoritmo o supportare più algoritmi. Potresti includere un identificatore di algoritmo non criptato, ma dovresti essere molto attento, in quanto un utente malintenzionato potrebbe cambiarlo in qualunque cosa desideri, aprendo la porta a attacchi di downgrade .
Ma tu vuoi farlo con una chiave pre-condivisa come alternativa a TLS, quindi c'è molto di più. TLS non fornisce solo riservatezza, ma gestisce anche la gestione delle chiavi e l'autenticità (tra le altre cose). Il problema con una chiave pre-condivisa è che devi essere molto consapevole dei vincoli. RFC 4107 vale la pena leggere.
Nonce / IV Riutilizzo
ChaCha20-Poly1305 e AES-GCM usano entrambi un nonce a 96 bit, il che significa che c'è una probabilità del 50% di ripetere dopo 2 48 messaggi quando si usano nonce casuali, quindi la chiave dovrebbe essere cambiata bene prima di questo ( NIST dice prima di 2 32 messaggi per GCM ). È anche possibile utilizzare un contatore invece di un IV casuale per determinati algoritmi, ma ci sono anche difficoltà con questo. A causa di questo rischio, le RFC per ChaCha20-Poly1305 e AES-GCM utilizzato in CMS entrambi richiedono che venga utilizzato un sistema di gestione delle chiavi automatizzato.
Il sistema di gestione delle chiavi più semplice è rappresentato dalle chiavi di crittografia a chiave simmetrica. Una chiave di contenuto viene generata casualmente per ciascun messaggio e utilizzata per crittografarla e una chiave pre-condivisa viene utilizzata per crittografare la chiave del contenuto da inviare insieme al messaggio.
Salt
La tua domanda menziona un salt, il che implica che stai usando una password. Questa è una cattiva idea . Per ricavare una chiave da una password è necessario un KDF lento come Argon2, bcrypt o PBKDF2, e un dispositivo vincolato probabilmente non è abbastanza veloce per eseguire tale KDF con un costo abbastanza alto da essere sicuro. Sarebbe molto meglio generare la chiave precondivisa con almeno 128 bit di entropia. Confondendo anche tu vuoi trasmettere il sale, il che implica che la password sta cambiando, ma questo contraddice il tuo commento che hai messo una "chiave" sul dispositivo.
L'autenticità
TLS fornisce l'autenticità, che è importante perché le modalità di crittografia comunemente utilizzate come CBC e CTR sono malleabili . È consigliabile utilizzare una modalità AEAD come ChaCha20-Poly1305 o AES-GCM o, in caso contrario, utilizzare un HMAC con Encrypt-Then-MAC.
Dispositivi vincolati
Su dispositivi vincolati che non sono in grado di generare casualità crittograficamente sicura (e quindi non possono generare una chiave nonce / IV o una chiave per messaggio casuale), una chiave precondivisa con un contatore nonce memorizzato potrebbe essere la migliore tu puoi fare. Devi solo essere molto attento a garantire che il riutilizzo di nonce sia impedito anche quando il dispositivo viene spento e riacceso il più facilmente possibile per cambiare la chiave se / quando necessario.