Reemplazo simple y liviano para SSL / TLS

24

El hardware de destino es una MCU más bien de baja potencia (ARM Cortex-M3 a 72MHz, con casi 64KB de SRAM y 256KB de flash), así que camine por la línea delgada aquí. Mi placa tiene Ethernet, y eventualmente obtendré lwIP (paquete de software ligero de TCP / IP FOSS) ejecutándose en él (actualmente con problemas). Sin embargo, también necesito algún tipo de alternativa superligera a SSL / TLS. Soy consciente de las múltiples implementaciones GPL de SSL / TLS para tales MCU, pero su huella sigue siendo bastante significativa. Si bien se adaptan, dado todo lo demás, no deje mucho espacio para los demás.

Mi tráfico no es HTTP, por lo que no tengo que preocuparme por HTTPS, y mi comunicación cliente / servidor puede ser completamente propietaria, por lo que la solución no estándar está bien. Buscando sugerencias sobre lo que podría ser minimalista y robusto (una seguridad débil no tiene ningún valor), una alternativa que me ayuda -

Encrypt my communication (C->S & S->C)
Do 2-way authentication (C->S & S->C)
Avoid man-in-middle attacks

No podré optimizar la biblioteca en el nivel de ensamblaje de ARMv7 y, por lo tanto, confiar completamente en mis habilidades de programación y en la optimización del compilador de GNU-ARM. Teniendo en cuenta lo anterior, ¿alguna sugerencia de cuáles podrían ser las mejores opciones?

C: Cliente, S: Servidor. Mi comunicación es todos los datos binarios.

    
pregunta mike.dinnone 20.04.2011 - 10:09
fuente

4 respuestas

31

Editar: después de un poco de esfuerzo, hice reimplementar una biblioteca SSL eficiente en RAM, que puede ejecutarse en el tipo de cantidad de RAM que se indica a continuación. Tiene muchas más características y flexibilidad que mis creaciones anteriores, y aún así es muy pequeño. Más importante aún, también es OpenSource (licencia MIT). Disfrute: enlace

Es posible implementar un cliente (o servidor) SSL / TLS en aproximadamente 21 kB de código ARM (pulgar), que requieren menos de 20 kB de RAM cuando se ejecuta (*). Sé que se puede hacer porque lo hice (lo siento, no de código abierto). La mayor parte de la complejidad de TLS proviene de su compatibilidad con muchos tipos de algoritmos criptográficos, que se negocian durante el protocolo inicial inicial; Si se concentra en un solo conjunto de algoritmos criptográficos, entonces puede reducir el código a algo que es bastante pequeño. Recomiendo usar TLS 1.2 con el conjunto de cifrado TLS_RSA_WITH_AES_128_CBC_SHA256 : para eso, solo necesitará implementaciones para RSA, AES y SHA-256 (para TLS 1.1 y anteriores, también necesitarías implementaciones para MD5 y SHA-1, lo cual no es difícil pero gastará unos cuantos kBytes de código adicionales). Además, puede hacer que sea sincrónico (en TLS simple, el cliente y el servidor pueden hablar simultáneamente, pero nada los obliga a hacerlo) y omitir la parte de "renegociación de reconocimiento" (el cliente y el servidor realizan un reconocimiento inicial) , pero pueden rehacerlo más tarde durante la conexión).

La parte más complicada de la implementación del protocolo es sobre los certificados. El servidor y el cliente se autentican entre sí usando sus respectivas claves privadas: con RSA, el servidor realiza un descifrado RSA, mientras que el cliente calcula una firma RSA. Esto proporciona autenticación siempre que el cliente y el servidor se conozcan entre sí las claves públicas; por lo tanto, envían sus claves públicas entre sí, envueltas en certificados que son blobs firmados. Un certificado debe validarse antes de su uso, es decir, su firma debe verificarse con respecto a una clave pública conocida a priori (a menudo denominada "CA raíz" o "ancla de confianza"). El cliente no puede usar ciegamente la clave pública que el servidor acaba de enviar, porque permitiría ataques de intermediario.

El análisis y validación del certificado X.509 es un poco complejo (en mi implementación, fue de 6 kB de código, de los 21 kB). Dependiendo de su configuración, puede tener opciones más ligeras; por ejemplo, si puede codificar la clave pública del servidor en el cliente, entonces el cliente simplemente puede usar esa clave y deshacerse del certificado del servidor, que es "solo un blob": no es necesario analizar, no es necesario un certificado, un protocolo muy robusto. También puede definir su propio formato de "certificado". Otra posibilidad es utilizar SRP , que es un mecanismo de intercambio clave en el que ambas partes se autentican entre sí con respecto al conocimiento de un valor secreto compartido (la magia de SRP es que es robusto incluso si el secreto compartido tiene una entropía relativamente baja, por ejemplo, es una contraseña); usa TLS_SRP_SHA_WITH_AES_128_CBC_SHA .

El punto aquí es que incluso con un protocolo personalizado, no obtendrás algo realmente más ligero que un TLS reducido, al menos si quieres mantenerlo robusto. Y diseñar un protocolo robusto no es fácil en absoluto ; TLS llegó al punto de ser considerado adecuadamente seguro a través de años de sangre y lágrimas. Por lo tanto, es realmente mejor reutilizar TLS que inventar su propio protocolo. Además, esto hace que el código sea mucho más fácil de probar (puede interoperar con implementaciones SSL / TLS existentes).

(*) De los 20 kB de RAM, hay un búfer de 16.5 kB para los "registros" entrantes, porque TLS indica que los registros pueden alcanzar ese tamaño. Si controla tanto el código del cliente como el del servidor, puede organizar un tamaño de registro máximo más pequeño, ahorrando así los requisitos de RAM. La sobrecarga por registro no es mucho (menos de 50 bytes en promedio), por lo que podría usar registros de 4 KB y tener una comunicación eficiente.

    
respondido por el Thomas Pornin 20.04.2011 - 14:52
fuente
3

TLS aún parece ser la herramienta para el trabajo, solo elija los cifrados con inteligencia y luego, determine cuál de las implementaciones de cifrado funciona bien en su plataforma. Además, las implementaciones oficiales de las bibliotecas criptográficas tienden a ser terriblemente lentas en comparación con las herramientas de pirateo, como los algoritmos de John The Destripador , así que quizás puedas usar estos. ¿Has probado MatrixSSL todavía?

    
respondido por el Marcin 20.04.2011 - 14:50
fuente
3

Hagas lo que hagas, iré con un protocolo existente que ha existido por un tiempo y eliminaré / codificará algunas opciones para hacerlo más ligero, en lugar de inventar tu propio protocolo.

Si sus necesidades son lo suficientemente simples como para poder hacerlo con claves simétricas compartidas previamente, entonces agregar un subconjunto de IPSEC a la pila TCP / IP parece que podría hacerse sin un gran espacio de código. Incluso podría ser posible mantener la interoperabilidad.

De manera similar, un SSL o Kerberos reducido es probablemente una opción, ya que no necesitará la mayoría de los aspectos más sofisticados de administración de claves y autenticación, ni la mayoría de los cifrados.

    
respondido por el frankodwyer 20.04.2011 - 15:50
fuente
0

Puede consultar MST (transporte seguro mínimo) enlace .

Proporciona las mismas garantías de seguridad que TLS, pero requiere una clave previamente compartida. Además, es muy pequeño (menos de 1000 LoC, sin AES) y, por lo tanto, puede ser revisado fácilmente por un experto.

    
respondido por el user161352 16.10.2017 - 15:21
fuente

Lea otras preguntas en las etiquetas