Producir hashes seguros para detectar la manipulación de datos

0

Tengo una aplicación de Android que se basa internamente en una base de datos SQLite que almacena datos de usuarios cifrados. Los datos se cifran utilizando AES-256, con una clave generada por el algoritmo PBKDF2-HMACSHA256. La aplicación tiene la necesidad de detectar la manipulación de los datos mediante métodos malintencionados o no malintencionados (es decir, corrupción de datos o alguien intencionalmente manipulando la base de datos).

Por lo que puedo decir, tengo dos opciones sólidas sobre cómo generar de forma segura un hash para representar estos datos. O bien, puedo confiar en un algoritmo HMAC-SHA256 con la misma contraseña utilizada para generar la clave AES-256 para generar firmas de los datos en cada fila de la base de datos. Alternativamente, podría generar un hash SHA-256 ordinario de los datos desencriptados almacenados en la memoria antes de volver a cifrarlos para actualizar la fila de la base de datos. Entonces, en teoría, solo el usuario autenticado con la clave correcta puede descifrar los datos y, por lo tanto, solo ese usuario puede generar esta "firma".

Aquí está mi pregunta: usar HMAC-SHA256 causará complicaciones con la forma exacta de conservar la contraseña como la clave o de alguna manera para aprovechar la clave SHA-256 como la clave HMAC. De cualquier manera, parece no necesariamente doloroso y la complejidad es, en general, algo nuevo para los sistemas seguros. ¿Sería igualmente seguro confiar en un hash SHA-256 ordinario de datos descifrados, como utilizar un algoritmo de hash de estilo HMAC? Al igual que en, ¿son igualmente difíciles / imposibles de forjar una firma?

    
pregunta dFrancisco 23.02.2018 - 17:44
fuente

3 respuestas

1

Lo ideal sería utilizar un algoritmo de cifrado autenticado integrado como AES-GCM, pero como ya tiene datos cifrados, vale la pena buscar opciones que no requieran que vuelva a cifrar todo.

La composición más segura de cifrado y autenticación es cifrar y luego autenticar . Su solución candidata para aplicar HMAC a los textos cifrados es, por lo tanto, la mejor. Sin embargo, asegúrese de incluir también todo el contexto relevante en el cálculo de HMAC:

  1. Cualquier IV que esté pasando al cifrado debe ser parte de la entrada al MAC.
  2. También puede tener sentido incluir otros datos contextuales en la entrada MAC. Por ejemplo, si hay una clave natural en la fila donde se almacenan los datos descifrados, incluida la entrada en la MAC, se defiende contra ataques en los que alguien intercambia los valores cifrados en diferentes registros. (Vea esta respuesta mía a una pregunta diferente .)

Para obtener la clave HMAC, tiene algunas opciones:

  1. PBDKF2 admite la generación de salidas largas, con una longitud de salida proporcionada por el usuario. Solo puede solicitar una salida más larga y usar la primera parte para el cifrado (tendrá el mismo valor que ya tiene) y los bits adicionales para el MAC. Grave inconveniente de esto: puede duplicar el tiempo de ejecución de las derivaciones de PBKDF2.
  2. Puede usar HKDF-HMAC-SHA256 para derivar subclaves de la clave que deriva de PBKDF2. Idealmente, desearía derivar tanto el cifrado como las claves MAC de la clave PBKDF2, pero para una compatibilidad con versiones anteriores, podría utilizar la clave maestra PBDKF2 para el cifrado como lo hace ahora, y una clave derivada de HKDF para MAC . HKDF es un algoritmo muy simple creado en HMAC, por lo que incluso si sus bibliotecas no lo tienen, no debería tener mucho miedo de implementarlo. (Si le está suministrando la salida de PBKDF2, solo necesita la función de expansión HKDF, y puede omitir el extracto de HKDF).
  3. Haga un descuento y use la misma clave derivada de PBKDF2 tanto para AES como para HMAC. El uso de la misma clave para ambos propósitos es malo en principio (como lo ha señalado @Scovetta), . Esto cuenta un poco como "vivir al límite", pero hay muchas más razones para sospechar que está bien que para sospechar que es malo. (Por otra parte, si su cifrado y su MAC estuvieran basados en AES, o si alguna vez existe la posibilidad de que pueda cambiar a un MAC basado en AES más adelante, usar la misma clave para ambos sería muy aterrador).

De estos me gustaría ir con # 2. Es el que tiene más principios y solo son unas pocas llamadas HMAC-SHA256 adicionales, a las que ya está llamando miles de veces con PBKDF2.

Hashing the plaintext no es una muy buena idea. El mayor problema es que permite a un atacante probar conjeturas en cuanto a qué plaintexts son: es exactamente el mismo tipo de ataque que las contraseñas de craqueo con funciones hash rápidas, las GPU solo pueden hacer conjeturas a altas velocidades.

    
fuente
2

Hay algoritmos disponibles que proporcionan protección contra la manipulación indebida. AES-GCM es uno de esos algoritmos. Por enlace

  

GCM es un algoritmo de cifrado autenticado diseñado para proporcionar autenticidad (integridad) y confidencialidad de los datos.

AES-GCM está disponible en Android API 26+. enlace Recomiendo usar un algoritmo que ya tenga un control de autenticidad incorporado al tratar de implementar este tipo de las cosas por su cuenta.

    
respondido por el saghaulor 23.02.2018 - 18:39
fuente
0

Primero, ¿contra qué estás tratando de protegerte? ¿Bits de bits aleatorios, o modificación intencional por un atacante? Si se trata de giros de bits aleatorios, entonces el cifrado de disco completo de Android podría ser suficiente para detectar esto, si está habilitado. Si es un ataque intencional, entonces deberías preguntar si ese mismo atacante sería capaz de obtener la misma clave y volver a MAC'ing la fila correctamente.

Suponiendo que aún necesita protección de integridad, ¿puede delegar esto en el controlador en lugar de hacerlo usted mismo? SQLCipher puede ser una solución viable e incluye MAC a nivel de página para la protección de la integridad.

Aunque GCM proporciona autenticación, hay algunas desventajas que debe ser consciente de.

No debe usar la misma clave tanto para el cifrado como para HMACing. En su lugar, cree una clave (de forma segura) y luego derive tanto el cifrado como la HMAC a partir de eso. Hay muchas maneras de hacer esto: por ejemplo :

x = <encryption key>
enc_key = HMAC-SHA-256(x, 'encryption key')
hmac_key = HMAC-SHA-256(x, 'hmac key')
    
respondido por el Scovetta 23.02.2018 - 19:30
fuente

Lea otras preguntas en las etiquetas