¿Algoritmo criptográfico para anonimizar cadenas de manera pronunciable?

7

NB: originalmente publiqué esto en SO ( link ), pero luego se da cuenta de que Security SE es más adecuado, ya que hay preguntas alrededor de Crypto-PAn, que es similar aquí

Tengo un archivo de registro de las consultas de la base de datos que me gustaría anonimizar. Estas se obtienen de los clientes y luego se analizan externamente. A los clientes les gustaría anonimizar estos datos lo suficiente como para proteger la información de identificación, pero aún así lo suficiente para permitir un análisis útil.

Algunas líneas pueden contener direcciones IP (por ejemplo, IP de origen). Creo que puedo usar algo como Crypto -Papá para anonimizar esos. Tengo entendido que este anonimato es inyectivo (1: 1) y repetible, pero también no reversible.

Del mismo modo, las líneas también pueden contener campos y valores, por ejemplo, { "name.first": "John" } .

Para los valores, me complace usar simplemente MD5 directo (o similar en el contenido), no es tan crítico que veamos lo que son.

Sin embargo, para los campos de la base de datos, nos gustaría preservarlos en un formato un tanto legible para las personas. Esto se debe a que haríamos un análisis de rendimiento basado en esos campos (por ejemplo, agrupando consultas por campos, etc.)

Por ejemplo, name.first podría convertirse en Tree.Blackboard .

Las restricciones son:

  • Cada palabra de entrada debe asignarse a un hash, y viceversa (entiendo que habrá algunas colisiones, pero espero que sean lo suficientemente raras).
  • Repetible: si tenemos varios archivos de registro, queremos que se genere el mismo hash cada vez, esto nos permitirá comparar los archivos de registro.
  • No reversible: idealmente, no debería haber una manera fácil de revertir el hash para obtener el nombre del campo original.
  • Legible para humanos: el hash debe ser legible / pronunciable por humanos, pero no necesariamente tienen que ser palabras en inglés válidas (por ejemplo, Flerti es aceptable, 037751d79d1ebfdd0664b2c66b8d66d1 no lo es)

Lo discutí con un colega, y una de las maneras que pensamos fue:

  • Tome el nombre del campo y páselo a través de un hash unidireccional estándar (por ejemplo, MD5).
  • Tome suficientes bits de orden inferior del hash resultante para asignarlos a un diccionario de palabras en inglés (por ejemplo, 1,000,000 de palabras válidas). Use el equivalente entero de esos bits y haga un mod para indexar una palabra en ese diccionario.

La idea es que: las palabras serían legibles y, al mismo tiempo, siempre consistentes (suponiendo que su diccionario permanezca igual).

Si algunas personas estaban preocupadas por los ataques de diccionario (es decir, el nombre de campo "nombre" siempre se asignaría para decir "Pizarra"), entonces esa persona podría tener su propio archivo de clave específico para eliminar el hash. Esto significa que sería repetible para ellos los archivos de registro anónimos (es decir, que "primer nombre" siempre se asignaría a "Billion" para ellos), pero no sería lo mismo que para otras personas que usan otros archivos de claves.

Pregunta 1 : ¿ya existe un algoritmo criptográfico (similar a Crypto-PAn) que se pueda usar para anonimizar cadenas de una manera pronunciable / legible?

Pregunta 2 : si no, ¿ve algún agujero deslumbrante en el enfoque simplista descrito anteriormente?

    
pregunta victorhooi 26.06.2015 - 06:18
fuente

2 respuestas

4

Puedes probar un hash de sílaba.

Comience con un algoritmo hash básico para digerir los identificadores de datos individuales; no es necesario que realmente sea criptográfico, y lo recomiendo en contra. La mayoría de las implementaciones producirán una matriz de bytes que es perfecta; unos pocos producirán una única primitiva más grande o matrices de primitivas más grandes, en cuyo caso querrá dividirlas en bytes.

Luego, busque o cree una búsqueda de posibles valores de byte que se asignen a pares de valores de consonantes simples (Ba, Be, Bi, Bo, Bu, Cha, Che, Chi, Cho, Chu, Da, De, Di, Do , Du etc). El orden de las sílabas y su asignación a los valores de bytes no importa; el hashing es la parte no reversible de la operación, no la asignación de sílabas. Recuerde que solo obtiene 256, y si usa un hash seguro, también podría ser conveniente incluir algunas asignaciones que agreguen información sin agregar una sílaba (un guión o vocales que se agregarían a la vocal de la sílaba anterior para crear un diptong o digraph).

Con un hash de suma de comprobación básico de 32 bits como FNV-1 o Murmur, esto le dará palabras de construcción aparentemente aleatoria en el rango de 2-4 sílabas con una tendencia promedio alta (y la posibilidad de palabras reconocibles de una sílaba son casi inexistente, especialmente si los ceros iniciales se tratan de la misma manera que los ceros en línea o en la matriz de bytes). Usando un hash criptográfico, es probable que tenga que plegar XOR los bytes, ya que algo como SHA-1 le dará palabras de 10 sílabas, por lo que recomendaría un hash criptográfico.

Probablemente sonará como un japonés de realidad alternativa, pero podrás pronunciar los identificadores resultantes. Para hacer que suene más en inglés, puede comenzar con una lista de las sílabas en inglés más comunes, como this . Sin embargo, esta lista incluirá sílabas que son comunes porque son prefijos o sufijos de las raíces de palabras, mientras que las inyectarás en lugares aleatorios de la palabra.

    
respondido por el KeithS 26.06.2015 - 18:08
fuente
2

¿Qué estás tratando de lograr? ¿Desea anonimizar una base de datos con datos confidenciales para poder compartirla de manera segura con un equipo de prueba de control de calidad externo sin comprometer el contenido? En este caso, anonimizar los nombres de personas y empresas no es suficiente, porque el resto de los datos también tiene una huella que permite sacar conclusiones al propietario de los datos. También dijo que cada dato debería asignarse a un hash y viceversa, pero no debería ser reversible. Esto es una contradicción, no es posible lograr ambos.

Con respecto a un algoritmo, observe cómo PGP crea huellas digitales. Son pronunciables y hashes, que consisten en una secuencia de palabras en inglés.

Si bien la función hash en sí misma no es reversible, los hashes permiten identificar de forma única un registro que pertenece a este hash.

Hay clones de código abierto de PGP disponibles, por lo que debería poder obtener el código fuente.

En lugar de hash, puede agregar un campo que complete con cadenas aleatorias generadas por un algoritmo como:

void Main()
{
    MakeRandomString(4).Dump();
}


private string MakeRandomString(int n)  
{  
    var bits = new List<string>()  
    {  
            "na",  "bla",  "chee",  "dee",  "ay",              
            "tree", "th",  "goo",  "foo",              
            "ook",  "ta",  "bee",              
            "zoo",  "ai",  "kawee",  "jam",  "ya"            
    };  

    StringBuilder sb = new StringBuilder();  
    Random r = new Random();  
    for (int i = 0; i < n; i++)  
    {  
        sb.Append(bits[r.Next(bits.Count)]);  
    }  

    return sb.ToString();  
}  

Esto creará palabras de fantasía aleatorias como:

cheekaweefoobla
yataaitree
deetreenana

Es un código ligeramente cambiado que tomé de aquí . Para exportar puedes usar ese campo como referencia. Será capaz de mapear la fila original. Puede mejorar el código anterior utilizando un generador criptográfico aleatorio.

    
respondido por el Matt 26.06.2015 - 08:49
fuente

Lea otras preguntas en las etiquetas