Tengo un mensaje que me estoy enviando y que estará sujeto a ataques de hombre en el medio. Por eso, me preocupa la integridad del mensaje que se mantiene entre el momento en que lo envío y el momento en que lo recibo.Mantenimiento de la integridad del mensaje
Se supone que una vez que me envíe el mensaje, no tendré disponible información sobre el mensaje enviado en el futuro. El mensaje es completamente autónomo.
Para ese fin, sé que debe hash el contenido del mensaje y comparar los valores antes de enviar el mensaje, y después de enviar el mensaje, si difieren, entonces el mensaje ha sido alterado.
Por supuesto, si el hombre en el medio sabe que el hash es realmente solo el hash de los contenidos del mensaje, tal como está, entonces porque el mensaje es autónomo, puede simplemente crear nuevos contenidos y aplicar el mismo algoritmo hash a los contenidos.
La pregunta es, ¿a qué longitud debo ir para aleatorizar el contenido del mensaje al generar el hash? ¿Cuándo llega al punto de rendimientos decrecientes?
En este caso, tengo un conjunto de pares clave/valor. Con ese fin, los pasos que sé que TENGO que tomar son:
- Agregue un salt al mensaje. La sal es un secreto para el resto del mundo. Se adjunta al contenido del mensaje antes de hash.
- Ordene los pares clave/valor de forma consistente antes de generar el hash.
- Si bien no es directamente relevante, se agregará una marca de tiempo al contenido de cada mensaje antes del hashing, para evitar ataques de repetición.
Estos son los pasos opcionales que estoy considerando:
- La transformación de las llaves antes de los solicito. He considerado invertirlos, luego ordenar por conteo/clave.
- Jugando con los separadores que separan los pares clave/valor (tanto para el separador para la clave/valor como para el separador para el par).
NOTA
mensaje privacidad es no un requisito aquí, así que no estoy buscando para el cifrado. Los valores deben transmitirse en texto sin formato.
Finalmente, ¿qué algoritmos hash debo evitar?
Específicos
que tienen un sitio ASP.NET MVC, que tengo un controlador que maneja la validación de entrada y persistencia.
Si (basado en una heurística, que no es importante lo que) la entrada se determina que es un intento de spam automatizado, un modelo de IDictionary<string, string>
se crea con los valores de entrada y una ViewResult se envía a una página general de CAPTCHA.
En esa vista, en la forma que contiene el control CAPTCHA, los contenidos del IDictionary<string, string>
se escribirán en campos de entrada ocultos, y la acción del formulario será la misma acción en la que se publicaron originalmente los contenidos. De esta forma, MVC puede recoger los valores cuando se reenvía el formulario.
Es por esto que no puedo encriptar los pares de clave/valor (o quizás puedo y debo decirme por qué y cómo).
Por supuesto, necesito agregar un valor más, que contiene el contenido del mensaje hash. Si ese valor está allí, entonces el controlador verificará que se mantenga la integridad del mensaje y permitirá que la entrada se mantenga si lo ha hecho.
Solución
he optado por ir con la clase SignedCms en el espacio de nombres System.Security.Cyrptography.Pkcs, que representa la signging y verificación de CMS/PKCS # 7 mensajes.
Elaborar, he creado un certificado auto-emitida con Makecert.exe y luego en mi código, yo uso el ejemplo aquí para firmar digitalmente los datos:
http://blogs.msdn.com/shawnfa/archive/2006/02/27/539990.aspx
Ahora, lo que debería se trata de mantener segura la contraseña de la clave privada exportada, así como la seguridad en el servidor, lo que reduce la programación.
Tendré que agregar una clave adicional para la marca de tiempo para los ataques de reproducción, pero eso no será demasiado difícil.
La respuesta va al Kalium, no para su initial post, pero para sus comentarios de seguimiento que señalaron el camino a las firmas digitales, y finalmente mi descubrimiento de cómo utilizarlas en .NET.
Gracias a todos los que contribuyeron.
@Kalium: No, la privacidad del mensaje no es un problema y es un poco exagerado. De hecho, la transparencia del mensaje es un requisito. – casperOne
Probablemente sea la mejor opción para garantizar la integridad del mensaje. No necesita encriptarlo, solo fírmelo. Incluso podría enviar la clave pública con él. – Kalium
@ Kalium: para ese fin, ¿tiene algún vínculo a buenos recursos PGP/GPG en .NET? Además, ¿qué pasa con el problema del "secreto compartido"? ¿El hecho de que firme el hash con una clave asimétrica hace que la clave privada sea el secreto, y niega la necesidad de organizar los datos para que sean hash de forma diferente? – casperOne