AES utilizando claves / IV derivadas. ¿Introduce una debilidad?

9

Estoy buscando una forma eficiente de cifrar múltiples campos en una base de datos con AES usando una sola clave global, utilizada en una gran aplicación web.

Obviamente, para reutilizar esta clave, se requiere un IV aleatorio único para cada campo que se va a cifrar.

Prefiero no introducir más campos en la base de datos para almacenar cada una de estas IV, por lo que el enfoque programático parece ser derivar estas IV de alguna manera.

Estoy jugando con el uso de cualquiera:

key = sha256(global_key + table_name)
iv = sha256(column_name + primary_key)

O incluso simplemente:

key = global_key
iv = sha256(table_name + column_name + primary_key)

Me inclino hacia el primero para generar claves por tabla.

Ya he ya leí que las IV no deben mantenerse en secreto. Así que estoy trabajando en la suposición de que una clave derivada o IV (incluso si el algoritmo se conoce), no es más insegura que cualquier otra IV no secreta, siempre que el original la clave permanece secreta .

La pregunta es:

¿Hay un error fatal en mi enfoque? ¿Estoy presentando alguna deficiencia grave que, en caso de que un adversario obtenga una copia de la base de datos, le facilitaría la recuperación de los datos en texto sin formato?

Me doy cuenta de que es potencialmente solicitar respuestas de una palabra.

Las sugerencias para esquemas alternativos / mejores son muy bienvenidas, así como las referencias a trabajos existentes y cómo implementan escenarios similares.

    
pregunta Leigh 13.11.2012 - 15:41
fuente

3 respuestas

5

Un enfoque potencialmente mejor sería almacenar el IV y el texto cifrado en una columna. De esta manera, puede generar IV de la forma más adecuada para su elección de modo de encriptación sin tener que agregar columnas.

Algo como "$AES-128-CBC$" + Base64.encode64(iv) + "$" + Base64.encode64(ciphertext) es similar al formato usado en crypt , fácilmente analizable, y estar codificado en Base64 es un poco más conveniente cuando se realizan consultas en la base de datos utilizando clientes de la línea de comandos.

    
respondido por el Stephen Touset 13.11.2012 - 19:04
fuente
3

Su enfoque es inseguro. Si modifica algún valor en la base de datos, estará cifrando un nuevo valor utilizando el mismo IV que utilizó para cifrar el valor anterior. (Los datos se almacenarán en el mismo lugar, por lo que el nombre de la tabla, el nombre de la columna y la clave principal permanecerán sin cambios). Esto podría comprometer la confidencialidad. El compromiso es especialmente malo si está utilizando un cifrado de flujo o AES-CTR o un modo similar, ya que luego ha cifrado dos valores diferentes utilizando el mismo flujo, una vulnerabilidad clásica de reutilización del flujo de clave (el teclado dos veces es altamente inseguro) .

En su lugar, es mejor hacer lo que otros recomiendan: generar un IV al azar y almacenarlo junto con el texto cifrado. De hecho, en la mayoría de los modos de operación, puede considerar que el IV es parte del texto cifrado.

    
respondido por el D.W. 14.11.2012 - 09:12
fuente
2

Supongo que estás usando el modo CBC ...

Yo diría que se trata de una infracción CWE-329 . El IV puede ser conocido como el atacante , pero debe ser aleatorio . Una solución más común a su problema es simplemente almacenar un valor aleatorio muy seguro y usarlo como su "IV".

Digamos que tienes una tabla llamada "secreto". El atacante tiene una vulnerabilidad de Inyección de SQL y ve esta tabla, también puede ver que el valor de la clave principal actual. Al calcular un hash simple de sha256, es capaz de predecir el próximo IV, o incluso calcular una tabla de futuros IV. (¡Dependiendo de su plataforma, la vulnerabilidad de Inyección SQL podría convertirse en un oráculo de descifrado! ¡Desagradable!)

Si construyera esto, usaría una función de derivación de claves adecuada, como PBKDF2. Estas son funciones más pesadas que hacen que sea más difícil para el atacante calcular o calcular en masa. No tiene que ser mucho más pesado, pero el valor resultante tiene que ser del mismo tamaño que su cifrado.

Otra posible solución es tener un "secreto IV" global. Pase iv_secret + column_name + primary_key a su función de derivación de clave para producir su IV. Debido al uso de un secreto, el IV ya no es un valor predecible y esto ya no es una violación de CWE-329. Además, este valor también es un nonce, no es probable que la misma IV se genere dos veces para dos valores diferentes ... (A menos que haya realizado una actualización, lo que sería una violación). Para mitigar esto, podría agregar un "número de versión" o una marca de tiempo de última modificación al cálculo IV.

    
respondido por el rook 13.11.2012 - 17:11
fuente

Lea otras preguntas en las etiquetas