Cifrar repetidamente (relleno aleatorio + const int32): ¿secreto de compromiso?

¿Algún esquema de encriptación me permitirá encriptar de manera segura el mismo número entero repetidamente, con diferente material aleatorio antepuesto cada vez? Parece el tipo de operación que podría meterme en problemas.

Quiero evitar el rastreo de elementos en mi aplicación web, pero aún tengo ID/URL de elementos persistentes para que los enlaces de contenido no caduquen con el tiempo. Mis requisitos de seguridad no son muy altos para esto, pero prefiero no hacer algo totalmente estúpido que obviamente comprometa el secreto.

// performed on each ID before transmitting item search results to the client
public int64 encryptWithRandomPadding(int32 id) {
    int32 randomPadding = getNextRandomInt32();
    return encrypt(((int64)randomPadding << 32) + id), SECRET);
}

// performed on an encrypted/padded ID for which the client requests details
public int32 decryptAndRemoveRandomPadding(int64 idToDecrypt) {
    int64 idWithPadding = decrypt(idToDecrypt, SECRET);
    return (int32)idWithPadding;
}

static readonly string SECRET = "thesecret";

Los ID/URL generados son permanentes, los ID cifrados están escasamente poblados (menos de 1 en uint32.Max son únicos, y podría agregar otro relleno constante para reducir la probabilidad de que exista una conjetura), y el cliente puede ejecutar la misma búsqueda y obtener los mismos resultados con diferentes identificaciones de representantes cada vez. Creo que cumple con mis requisitos, a menos que haya un problema criptográfico flagrante.

Ejemplo:

 encrypt(rndA + item1)   -> tokenA
 encrypt(rndB + item1)   -> tokenB
 encrypt(rndC + item2)   -> tokenC
 encrypt(rndD + item175) -> tokenD

Aquí, no hay forma de identificar que tokenA y tokenB apuntan a elementos idénticos; esto evita que una araña elimine resultados de búsqueda duplicados sin recuperarlos (mientras que la recuperación incrementa el medidor de uso). Además, es posible que item2 no exista.

Sabiendo que volver a ejecutar una búsqueda devolverá el mismo int32 rellenado de varias maneras con el mismo secreto, ¿Puedo hacer esto de forma segura con cualquier algoritmo criptográfico popular?? ¡Gracias, expertos en criptografía!

nota: este es un seguimiento de una pregunta que no funcionó como esperaba: Cifrar entero con un secreto y sal compartida

preguntado el 29 de julio de 12 a las 05:07

Si las identificaciones no cambian o caducan, cualquier persona puede simplemente recordar las que ha visto y no puede hacer que las olvide. Puede asignar identificaciones al azar de un gran conjunto de elementos para que sean difíciles de enumerar, pero eso no hará que sea difícil recordarlos. Por supuesto, puede limitar la cantidad de ID que se pueden solicitar desde una IP durante un período de tiempo determinado. ¿Eso ayuda en algo? -

@qsario: Gracias. De hecho, me parece bien que la gente recuerde los que ha visto. Debido a que millones de URL representarán el mismo elemento y millones de URL no serán válidas, la URL no ayuda a rastrear mi contenido. De hecho, planeo, además, implementar una cuota diaria para inspeccionar artículos. -

1 Respuestas

Si su encriptación es segura, entonces el relleno aleatorio hace que el descifrado no sea ni más fácil ni más difícil. Para un mensaje tan corto, de un solo bloque de largo, o todo está comprometido o nada lo está. Incluso con un cifrado de flujo, aún necesitaría la clave para llegar más lejos; el punto de un buen cifrado es que no necesita aleatoriedad adicional. El relleno cero u otros mensajes conocidos de al menos un bloque de largo al principio obviamente deben evitarse si es posible, pero ese no es el problema aquí. Es puro ruido, y una vez que alguien descubría eso, simplemente saltaban y comenzaban a partir de ahí.

Ahora, en un cifrado de flujo, puede agregar toda la aleatoriedad al principio y los bytes posteriores seguirán siendo los mismos con la misma clave, no lo olvide. En realidad, esto solo hace algo para un cifrado de bloque, de lo contrario, tendría que xor los bits aleatorios en el valor real para obtener algún uso.

Sin embargo, es mejor que use una MAC como relleno: con el cifrado adecuado, la Mac cifrada no revelará ninguna información, pero parece semialeatoria y puede usarla para verificar que no hubo errores o ataques maliciosos durante descifrado Cualquier función hash que desee puede crear el MAC, incluso un simple CRC-32, sin revelar nada después del cifrado.

(Un criptógrafo podría encontrar una manera de eliminar un poco debido a la relación, toneladas de textos sin formato si supiera de antemano cómo estaban relacionados, pero eso aún está mucho más allá de la practicidad).

Como preguntó antes, puede agregar de forma segura una sal sin cifrar delante de cada mensaje; un salt solo puede comprometer un valor encriptado si la implementación está rota o la clave está comprometida, siempre que el salt se mezcle correctamente con la clave, especialmente si puede mezclarlo con el programa de clave expandido antes del descifrado. Los algoritmos hash modernos con muchos bits son realmente buenos en eso, pero incluso mezclarlos con una clave de entrada regular siempre tendrá la misma seguridad que la clave sola.

Respondido 29 Jul 12, 05:07

La aleatoriedad no pretende ayudar a la cifrado, sino para 1) evitar la determinación programática de si un elemento en los resultados de búsqueda ya se ha visto 2) hacer que varias URL aparentemente aleatorias representen el mismo ID de elemento. Estos factores significan que una herramienta de rastreo no puede identificar si el contenido de una URL ya ha sido rastreado sin solicitar el contenido (que luego se abordará mediante una cuota diaria). Mi preocupación es que las múltiples representaciones del mismo contenido con diferentes rellenos en el bloque puedan debilitar seriamente algo. - Shannon

Si uso cualquier valor constante (como la dirección MAC) como único relleno, el abusador con la aplicación de rastreo puede simplemente inspeccionar las URL devueltas en los resultados de búsqueda para determinar si ya se han visto. - Shannon

Creo que solo debilitaría el cifrado si pudieran determinar fácilmente que en realidad eran lo mismo. En este caso, probablemente podría devolver un GUID nuevo cada vez y asignar cada uno a un ID real en su tabla; no hay necesidad de encriptación en absoluto. Eres el único que puede mapear uno al otro entonces. Si purga los GUID de vez en cuando, vencerá a la araña por completo. - SilverbackNet

Estoy de acuerdo, un GUID sería una excelente respuesta, pero también me gustaría poder enviar correos electrónicos, tal vez incluso marcar la URL, de ahí mi deseo de una identificación persistente. Un usuario podría encontrar intencionalmente una búsqueda que solo arrojara un resultado y ejecutar la búsqueda repetidamente para recopilar variantes cifradas de la identificación. O tal vez hay una debilidad mucho más grave al devolver los mismos 1000 resultados 100 veces. Creo que el termino se llama en.wikipedia.org/wiki/Differential_cryptanalysis , y parece que ninguno de los algoritmos actualmente populares tiene ataques que son accesibles para un laico? - Shannon

Estaba tratando de usar DES, aunque está envejeciendo, porque tengo acceso listo para usar en .NET y puedo cifrar bloques de tamaño pequeño (64 bits). No he encontrado ningún artículo que sugiera que es especialmente vulnerable al criptoanálisis diferencial, por lo que probablemente continuaré con él. Aceptaré su respuesta en función de su comentario sobre los textos sin formato, que me ayudó en el camino de Google hacia el criptoanálisis diferencial. ¡Gracias! - Shannon

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.