¿Formato común para enviar datos cifrados + IV?

3

Tengo una aplicación que recibe datos de terceros usando varios protocolos: MQTT, HTTP, AMQP, ...
Algunos clientes no pueden usar TLS (dispositivos iot sin soporte TLS), por lo que necesitamos encontrar una forma compacta y fácil de recibir datos cifrados.

Mi idea es utilizar un algoritmo simétrico (AES256 o similar), pero ¿cómo puedo formalizar cómo se transmiten los datos?

Junto con los datos cifrados también necesitamos pasar un InitializationVector . Existe un formato de "contenedor" común que explica cómo debe empaquetar encryptedData + IV ?

Por supuesto, podemos crear nuestro propio formato, tal vez utilizando ASN.1 o algún otro formato de serialización, pero si existe algo, será más fácil de explicar a todos los desarrolladores.

ACTUALIZACIÓN
¿Puede Sintaxis criptográfica de mensajes (CMS PKCS 7) ser una solución válida? ¿O es demasiado complejo de implementar en dispositivos iot pequeños?

ACTUALIZACIÓN 2 Como lo señaló @AndrolGenhald, no necesito pasar la sal si guardo la llave dentro del dispositivo. He eliminado el requisito de sal.

ACTUALIZACIÓN 3 Sabemos que usar TLS es la mejor solución y, de hecho, para la mayoría de los dispositivos podemos usarla. Desafortunadamente, algunos terceros desarrolladores me dicen que no tienen TLS en un tipo de dispositivo. No sé exactamente el detalle (probablemente debería investigar mejor ...). Nos piden que proporcionemos una manera de enviar datos cifrados sin TLS.

    
pregunta Davide Icardi 28.07.2018 - 11:16
fuente

4 respuestas

2

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.

    
respondido por el AndrolGenhald 31.07.2018 - 17:34
fuente
1

Como de costumbre, probablemente no sea una buena idea rodar su propio algoritmo de cifrado (y eso incluye el formato de transmisión). Recomendaría utilizar el formato OpenPGP, que ha estandarizado la transmisión del vector de inicialización, semilla para la derivación de clave de la frase de contraseña, el propio texto cifrado, etc.

Puede instalar gpg y usarlo desde una línea de comando (vea, por ejemplo, here ), y / o use BouncyCastle's implementación. Hay algunas preguntas sobre BouncyCastle y GPG en SE, ver por ejemplo this que cubre específicamente la interoperabilidad de Java / GPG. También hay un simple byte[] decryptor / encryptor servicio implementado en los ejemplos de BouncyCastle que pueden servir como punto de partida.

    
respondido por el TheWolf 31.07.2018 - 12:49
fuente
0
  

Mi idea es utilizar un algoritmo simétrico (AES256 o similar), pero ¿cómo puedo formalizar cómo se transmiten los datos?

AES256 es un algoritmo simétrico fino para usar. Sin embargo, también tienes que elegir un modo y usarlo correctamente. Le sugiero que utilice un modo de cifrado autenticado de AES (como GCM), en cuyo caso el cifrado se complementa con un MAC (como GMAC en GCM). Un modo de cifrado autenticado realiza el cifrado y el etiquetado de integridad (a través del MAC) de sus datos para que no solo se mantenga en secreto, sino que no se pueda modificar sin que usted lo sepa.

  

Junto con los datos cifrados también necesitamos pasar un InitializationVector. ¿Existe un formato de "contenedor" común que explica cómo debe empaquetar encriptadoData + IV?

Debe crear un nuevo IV aleatorio cada vez que cifre los datos. La IV es simple concatenada al principio o al final de la salida de texto cifrado del cifrado AE. No se requiere ningún contenedor específico, por sí solo, simplemente envíe IV+ciphertext (la etiqueta MAC está implícita en la salida de texto cifrado del modo AE) o envíe ciphertext+IV , realmente no importa.

Lo que importa en el modo es que tiene una forma segura de almacenar las claves de cifrado en el dispositivo y que genera un nuevo IV aleatorio cada vez que cifra los datos para enviar.

En el sistema que ha descrito (donde no puede usar TLS), probablemente tendrá que distribuir claves simétricas secretas con los puntos finales y mantenerlas seguras. Esta será la parte difícil de tu problema. Si tiene TLS, realmente no necesita preocuparse por esto, ya que solo necesita la clave pública del servidor, que no necesita estar seguro en todos y cada uno de los dispositivos del mundo.

    
respondido por el hft 01.08.2018 - 03:20
fuente
0

En los comentarios usted dice que no hay restricción de software. Mi consejo es que incluya la biblioteca OpenSSL, o una biblioteca de cifrado similar, dentro de su software y deje que maneje el canal TLS, no es necesario utilizar su propio esquema de cifrado

Además, usar solo AES para el cifrado simétrico deja el problema de cómo intercambiar las claves simétricas para ese cifrado. Codificarlo es un mal consejo y hacer un esquema de intercambio clave se deriva de la reimplementación de TLS o de la propia, en ambos casos también es un mal consejo

    
respondido por el Mr. E 01.08.2018 - 04:12
fuente

Lea otras preguntas en las etiquetas