¿Es seguro usar el HMAC de una cosa como sal para otro HMAC?

4

Problema

Estoy tratando de explicar el escenario completo en los siguientes párrafos. Creo que esto es importante para obtener algún contexto en el que se formule la pregunta, así que, por favor, tengan paciencia, incluso si es un muro de texto.

Actualmente tengo la tarea de anonimizar los datos de forma segura. La idea es usar HMAC(<string to anonymize>, key) para anonimizar los datos para que no se puedan revertir. Por ejemplo, si tiene un ID de cliente ( CUST299128218 ) esto sería HMAC-ed usando SECRET como la clave para 543a36dd07fe4a3fa4a2db202546eaaccaef71f871ebafe11de3b54784ba266e . Dado que queremos realizar un análisis sobre los datos anónimos, es importante que la misma ID de cliente siempre genere el mismo resumen HMAC. Entonces no podemos desechar la clave secreta , ya que necesitamos anonimizar los datos futuros con la misma clave.

Obviamente, la clave debe almacenarse en un lugar seguro para que no salga. De lo contrario, alguien que conozca un ID de cliente podría encontrar fácilmente a ese cliente específico en los datos anónimos. Por diversos motivos técnicos / organizativos, no podemos utilizar un módulo de seguridad de hardware para almacenar la clave. Así que eché un vistazo a la Bóveda de HashiCorp, que parece ser un buen ajuste para esto, ya que proporciona una API REST donde puede asignarle un texto plano y devuelve el HMAC de este texto simple utilizando un archivo almacenado previamente. llave. La clave nunca abandona la Bóveda, que es mucho mejor que tener la clave almacenada en alguna propiedad de configuración del software de anonimización.

Sin embargo, estamos hablando de grandes cantidades de conjuntos de datos para ser anonimizados (unos pocos cientos de miles hasta unos pocos millones por día) y es previsible que se llame la API de Vault para cada conjunto de datos (posiblemente varias veces, si es necesario anonimizar varios elementos, se producirá una carga general que puede sobrecargar la infraestructura que tenemos disponible para esto.

Solución propuesta

Por lo tanto, tuve esta idea: ¿Qué pasaría si usara una cadena fija (por ejemplo, 'customer_id_secret_bootstrap' ) y permitiera que Vault cree un HMAC al usar la clave secreta? Luego uso este HMAC como clave secreta para el HMAC real en los datos para anonimizar. En términos funcionales:

temp_key = CALL_VAULT('customer_id_secret_bootstrap')
anonymized_text = HMAC( <plaintext>, temp_key)

De esta manera solo pude hacer una llamada a Vault y mantener la clave temporal en la memoria. Siempre debo recuperar la misma clave temporal de Vault (ya que es un HMAC), pero la clave original (que se usa para derivar la clave temporal) nunca abandona la bóveda y cuando el programa sale, la clave temporal no se puede volver a crear. sin acceder a la bóveda. De esta manera, garantizaría la seguridad de la clave sin tener un millón de llamadas a la Bóveda.

Pregunta

Ahora, sabiendo que no soy un experto en seguridad, esta puede ser una idea terrible por razones desconocidas para mí. Por lo tanto, me gustaría compartir esto con sus expertos aquí. ¿Puede decirme si es una buena o mala idea y si es una mala idea? ¿Podría sugerir algún enfoque alternativo que garantice la seguridad de la clave y sea escalable?

Actualizar / Editar

Como indican muchas respuestas, no es suficiente para simplemente reemplazar las ID, ya que hay otros campos que se pueden usar para correlacionar la información con un pequeño conjunto de personas o incluso con una sola persona (por ejemplo, las marcas de tiempo son excelentes para esto). También nos encargamos de esto eliminando o reemplazando dicha información para asegurarnos de que esto no pueda suceder (tenemos una lista de verificación muy larga con respecto a estas cosas, que se basa en estándares de anonimización). Simplemente no quería introducir esos detalles aquí, ya que la pregunta ya es muy larga.

    
pregunta Jan Thomä 02.11.2017 - 12:08
fuente

2 respuestas

1

Como Luc señala , probablemente ya lo esté haciendo mejor que la mayoría de las personas. ¡Merece la pena por preocuparse por la privacidad de sus clientes!

Aquí tenemos tres sistemas diferentes, por orden de seguridad:

  1. Solo usa una clave secreta almacenada en alguna configuración.
  2. Su sistema: usando una bóveda en combinación con una clave almacenada en la configuración.
  3. Solo usando una bóveda.

El problema con el # 1 es obvio. Cualquier atacante que tenga acceso a su sistema puede robar la clave y luego usarla para realizar valores de hash de fuerza bruta en su propia computadora. Eso es malo.

Con el # 2 obtienes algo más de seguridad. Alguien debe entrar en tu sistema y robar CALL_VAULT('customer_id_secret_bootstrap') . Esto es más difícil, porque tienen que tomarlo de la memoria de trabajo y no del disco. Además, solo está disponible cuando el sistema se está ejecutando. Por lo tanto, no terminará accidentalmente en copias de seguridad, etc. Pero un atacante que obtenga el secreto puede usarlo en su propio sistema para forzar a los HMAC sin conexión.

Aquí es donde # 3 es más fuerte. Un atacante que obtiene acceso a su sistema no puede robar nada, porque la llave no saldrá de la bóveda. El atacante puede intentar descifrar hashes de ID de clientes en su sistema llamando a la bóveda, pero no puede simplemente robar todos los hashes e intentar descifrarlos en la privacidad de su propio hogar.

Entonces, si bien # 3 es más seguro que # 2, depende de usted juzgar si la seguridad adicional vale el precio (en rendimiento reducido, etc.). Eso depende de su modelo de amenaza y de la importancia de la seguridad de esta información.

    
respondido por el Anders 02.11.2017 - 13:59
fuente
1

Permítame enumerar las suposiciones / situación:

  • Tiene una gran base de datos con ID de clientes y otros campos para cada cliente.
  • Desea anonimizar esto para ejecutar análisis. La organización aún sabrá la ID del cliente original (no la borras permanentemente), pero la persona que realiza el análisis no lo hará.
  • Otros campos para el cliente también deberán anonimizarse.
  • Se está preguntando si puede usar la ID de cliente anonimizada como clave para el HMAC de los otros campos.

La respuesta es no, esto no sería seguro. La persona que realiza un análisis conoce la identificación anónima del cliente y solo puede usarla cuando se fuerza a otros campos.

Otra opción es crear una clave aleatoria para cada cliente y almacenarla en la base de datos con los datos del cliente. Esto significa que no necesita una "bóveda" o un módulo de seguridad de hardware: simplemente lea algunos bytes de /dev/urandom y guárdelos con los datos del cliente. Luego use esto como una clave para anonimizar otros campos.

Me imagino que la base de datos se verá así:

+---------+------------+------------+-------------------+
| ID      | Name       | Money      | Anonymization key |
+---------+------------+------------+-------------------+
| CUST999 | Jon Jonson | 3.14159265 | b2aZSo2D9erqwanrf |
+---------+------------+------------+-------------------+

Luego anonimizar:

customer = database.read();
anon = new Customer();
anon.ID = anonymize(customer.ID, customer.AnonymizationKey)
anon.Name = anonymize(customer.Name, customer.AnonymizationKey)
anon.Money = customer.Money //Assuming you don't want to anonymize every field.
print(anon)

La función anonymize(data, key) podría ser un HMAC como usted sugirió. Sin embargo, creo que El comentario de Stephane es realmente bueno: mencionan el uso de un hash lento para evitar el forzamiento de los brutos. Podría usar un algoritmo de almacenamiento de contraseñas (Bcrypt, Scrypt, Argon2 o PBKDF2, sin ningún orden en particular) para hacer las cosas más seguras. Sin embargo, como hablas de muchos registros, puedo imaginar que esto no es posible (o solo con factores de bajo costo), pero puedes investigarlo.

Por cierto, muchas personas intentan simplemente marcar el ID del cliente (por ejemplo, un número de teléfono) para que el departamento de mercadotecnia pueda decir con franqueza que está anonimizado, a pesar de que es de fuerza trivial. Esto es mejor ya, ya que implica una clave secreta. Y además de eso, estás pensando en las medidas adecuadas para mantener esa clave en secreto. +1 por eso!

    
respondido por el Luc 02.11.2017 - 12:51
fuente

Lea otras preguntas en las etiquetas