Cuando se usan AES y CBC, ¿puede el IV ser un hash del texto plano?

15

[Originalmente en programmers.stackexchange.com con título: ¿Puede cifrar con AES + CBC y buscar los datos cifrados ]

Básicamente, voy a utilizar el Estándar de cifrado avanzado con el modo de encadenamiento de bloques de cifrado o el modo de retroalimentación de cifrado o el modo de realimentación de salida (aún no lo he decidido). Cada modo requiere un vector de inicialización. La cosa es que quiero hacer que la cadena encriptada se pueda "buscar" de esta manera:

Supongamos que tengo una lista de tablas de base de datos junto con un "nombre para mostrar" para cada tabla. Conceptualmente, la lista se vería así (he usado {xxx} para significar la forma cifrada de xxx, y [IVx] para significar un vector de inicialización):

ENC_DISPLAY_NAME         | ENC_TABLE_NAME
------------------------ | -----------------
[IV1]{John's table}      | [IV2]{TABLE_3574}
[IV3]{Eric's list}       | [IV4]{TABLE_3100}
                         |
[IV5]{Darren's projects} | [IV6]{TABLE_2823}
[IV7]{Paul's contacts}   | [IV8]{TABLE_5843}

Ahora suponga que quiero permitir una búsqueda en ENC_DISPLAY_NAME. (Las búsquedas de igualdad son todo lo que se necesita.) Necesito tener alguna forma de saber qué vector de inicialización se usa en el nombre de visualización que quiero encontrar.

Creo que debería calcular un hash de 128 bits (tal vez un CRC) del nombre para mostrar, y usarlo como IV para calcular la cadena cifrada. Es decir, si quiero almacenar los "proyectos de Darren", debería hacer algo como esto:

AESKey key = ...;
String str = "Darren's projects";
CRCType crc = ComputeCRC(str);

BinaryString enc = crc.ToBinaryString ( ).Concat
    (EncryptWithAESandCBC(str, key, (IVType)crc));

INSERT INTO MY_TABLE(ENC_DISPLAY_NAME,ENC_TABLE_NAME) VALUES(enc, ...);

Si quiero buscar la cadena en su lugar, sigue los mismos pasos excepto el último, y luego SELECT * FROM MY_TABLE WHERE ENC_DISPLAY_NAME=enc .

¿Se ha intentado esto antes? ¿Hay algún riesgo (seguridad)?

[Pregunta relacionada: Compute ¿La clave de cifrado AES dada el texto simple y su texto cifrado? ]

    
pregunta Null Pointers etc. 16.06.2011 - 16:56
fuente

3 respuestas

18

Un hash computado sobre el texto simple tendría las características correctas para una IV, en lo que se refiere a la "aleatoriedad uniforme". Esto es para una función hash criptográficamente segura , no un CRC. Más bien, algo como SHA-256. Un CRC no es de ninguna manera lo suficientemente seguro para la criptografía.

Sin embargo , el IV debe ser conocido por quien descifre, por lo que debe almacenarse a lo largo del mensaje cifrado. Si la IV se calcula con una función de hash del texto sin formato, esto permite realizar un ataque de diccionario en el texto sin formato (intente con el posible texto sin formato hasta que se encuentre uno que coincida con el hash). Derrotar los ataques de diccionario ya es bastante difícil para las contraseñas, que están destinadas a ser seguras y de apariencia aleatoria; por lo tanto, para algo tan completamente no aleatorio como un nombre de visualización, realmente debería usar un IV generado a partir de un generador de números aleatorios criptográficos adecuadamente seguro, no un hash calculado a partir del texto simple. No cambiará sus costos de almacenamiento, ya que el IV debe almacenarse de todas formas, independientemente de cómo lo genere.

    
respondido por el Thomas Pornin 16.06.2011 - 18:00
fuente
5

Respuesta corta: IV debe ser aleatorio y enviado en claro.

Debe tener cuidado de no filtrar información sobre el texto sin formato en su hash. no debe ser posible llegar al texto sin formato con una tabla de arco iris de su hash. Por lo tanto, un valor de sal, almacenado en un archivo de configuración, no en la base de datos, está en orden.

Dicho esto, sugiero esto:

  • Usa un IV aleatorio, almacenado como lo haces ahora
  • almacene un hash con sal de los datos de texto sin formato en otra columna
  • busque el hash salado para recuperar el IV aleatorio y el texto cifrado

Entonces en tu ejemplo, tendrías esto:

NC_DISPLAY_NAME                                            | ENC_TABLE_NAME
-----------------------------------------------------------+------------------
hash(salt+"Darren's projects"), [IV5]{Darren's projects}   | [IV6]{TABLE_2823}

Por supuesto, el hachís salado no está exento de riesgos. Es más bajo de lo que intentabas evitar, pero todavía está presente. Si ese riesgo es demasiado alto, puede cifrar el hash de texto sin formato (con otra clave AES) en el modo ECB y buscarlo. Así tu mesa se verá así:

NC_DISPLAY_NAME                                               | ENC_TABLE_NAME
--------------------------------------------------------------+------------------
{k1 hash("Darren's projects")}, [IV5]{k2 Darren's projects}   | [IV6]{TABLE_2823}

Hacer el hash te da la entropía (blanqueo de entrada) equivalente a usar un IV (pero no tengo el poder matemático para confirmarlo). El cifrado le brinda protección contra las tablas y diccionarios de arco iris.

Sabes que tendrás una compensación de seguridad de velocidad cuando forzar brutalmente tu índice de búsqueda llevará más tiempo que la fuerza bruta del texto cifrado aleatorio IV.

    
respondido por el ixe013 16.06.2011 - 17:21
fuente
0

Si va a poner el hash del contenido allí mismo, entonces se dará cuenta de que su cifrado solo le dará otra copia de los datos. Si todo lo que está usando es una búsqueda, entonces todo lo que necesita es el hash (salvo colisiones, de todos modos). Por lo tanto, cualquier atacante que busque una fila específica basada en su nombre puede encontrarla sin saber la clave simplemente ignorando la parte cifrada de los datos y buscando el hash de lo que está buscando.

Ahora, si el resumen que está utilizando es un HMAC, y no solo CRC o un hash, podría estar bien. Pero tenga en cuenta que debe tener cuidado de no divulgar información adicional con él.

    
respondido por el Yuliy 21.06.2011 - 23:28
fuente

Lea otras preguntas en las etiquetas