Para responder a la pregunta de cómo empaquetar el texto cifrado y IV, la concatenación debería ser suficiente: IV || ciphertext || tag
. Este formato es conveniente porque permite la transmisión de encriptación. Usted genera y envía el IV, transmite el cifrado, luego calcula y envía la etiqueta de autenticación (sin embargo, la salida del descifrado no se puede transmitir, ya que la etiqueta debe verificarse primero).
La desventaja, por supuesto, es que hace que sea más difícil cambiar el algoritmo o admitir múltiples algoritmos. Podría incluir un identificador de algoritmo no encriptado, pero tendría que ser muy cuidadoso, ya que un atacante podría cambiarlo a lo que quiera, abriendo la puerta a ataques de degradación .
Pero desea hacer esto con una clave precompartida como alternativa a TLS, por lo que hay mucho más que eso. TLS no solo proporciona confidencialidad, también maneja la administración de claves y la autenticidad (entre otras cosas). El problema con una clave precompartida es que debe ser muy consciente de las restricciones. Vale la pena leer RFC 4107 .
Reutilización de Nonce / IV
ChaCha20-Poly1305 y AES-GCM usan un nonce de 96 bits, lo que significa que hay un 50% de posibilidades de repetición después de 2 mensajes 48 al usar nonces aleatorios, por lo que la clave debe cambiarse bien antes de eso ( NIST dice antes de 2 32 para GCM ). También es posible usar un contador en lugar de un IV aleatorio para ciertos algoritmos, pero también hay dificultades con eso. Debido a este riesgo, los RFC para ChaCha20-Poly1305 y AES-GCM como se usa en CMS, tanto requiere que se use un sistema de administración de claves automatizado.
El sistema de administración de claves más simple es el de claves de cifrado de claves simétricas. Se genera aleatoriamente una clave de contenido para cada mensaje y se usa para cifrarla, y se utiliza una clave precompartida para cifrar la clave de contenido que se envía junto con el mensaje.
Sal
Su pregunta menciona una sal, lo que implica que está usando una contraseña. Esta es una mala idea . Para obtener una clave de una contraseña se requiere un KDF lento como Argon2, bcrypt o PBKDF2, y es probable que un dispositivo restringido no sea lo suficientemente rápido para ejecutar un KDF con un costo lo suficientemente alto como para estar seguro. Sería mucho mejor generar la clave precompartida con al menos 128 bits de entropía. Confusamente, también desea transmitir el salt, lo que implica que la contraseña está cambiando, pero esto contradice su comentario de que ha puesto una "clave" en el dispositivo.
Autenticidad
TLS proporciona autenticidad, lo cual es importante porque los modos de cifrado utilizados comúnmente como CBC y CTR son maleable . Sería mejor usar un modo AEAD como ChaCha20-Poly1305 o AES-GCM, o, en su defecto, utilizar un HMAC con Encrypt-Then-MAC.
Dispositivos restringidos
En los dispositivos restringidos que no son capaces de generar aleatoriedad criptográficamente segura (y, por lo tanto, no puede generar un nonce / IV aleatorio o una clave por mensaje), una clave precompartida con un contador de nonce almacenado podría ser la mejor tu puedes hacer. Solo debe tener mucho cuidado para asegurarse de que se evita la reutilización de nonce, incluso cuando el dispositivo tiene un ciclo de encendido, y hacer que sea tan fácil como sea posible cambiar la clave si / cuando sea necesario.