2009-04-02 12 views
6

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:

  1. Agregue un salt al mensaje. La sal es un secreto para el resto del mundo. Se adjunta al contenido del mensaje antes de hash.
  2. Ordene los pares clave/valor de forma consistente antes de generar el hash.
  3. 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:

  1. La transformación de las llaves antes de los solicito. He considerado invertirlos, luego ordenar por conteo/clave.
  2. 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.

Respuesta

6

Creo que PGP/GPG es lo que quiere aquí.

+0

@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

+1

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

+0

@ 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

1

Quiere un Digitally Signed message. Usando GPG puede firmar el mensaje sin encriptarlo. Pero nadie podrá manipularlo, porque ellos no pueden generar el hash - solo usted puede porque el hash usa su clave privada.

0

Probablemente debas firmar digitalmente el mensaje (por lo tanto, PGP/GPG recomendado por Kalium es relevante como una opción). Cualquier hash puro que puedas crear puede ser recreado por el atacante. La firma digital - usando su clave de firma privada para que su clave pública pueda ser utilizada para verificarlo - es la solución. Cualquier otra cosa es un ejercicio inútil.

0

Suponiendo que no se puede pasar cualquier información a través de un canal "seguro" (es decir, el hash) así es como usted lo haría:

  1. Hash del mensaje, luego firme el hash con una clave privada. Incluya el hash firmado en el mensaje.
  2. Cuando recibe el mensaje, use la clave pública para descifrar el hash firmado y verifique que coincida con el hash real del mensaje.

Un atacante no podría "falsear" un mensaje, ya que necesitarían tener su clave privada para encriptar su nuevo hash.

Como otros han mencionado, esto es simplemente la vainilla firma digital y puede ser manejado por algo así como PGP/GPG

2

El enfoque más directo para permitir su aplicación para verificar que sus propios mensajes no han sido alterados sería usar un código clave de autenticación de mensaje hash. El mensaje se envía sin cifrar, pero también incluye un hash para evitar manipulaciones. El hash depende tanto del contenido del mensaje como de una clave secreta. El hombre en el medio no puede forjar un hash en un mensaje alterado sin conocer la clave. Como su aplicación crea y verifica los mensajes, nunca necesita divulgar la clave secreta.

Recomiendo especialmente la implementación descrita en RFC-2104 http://www.ietf.org/rfc/rfc2104.txt, ya que ha sido cuidadosamente pensada para evitar la mayoría de las posibles trampas.

Si las partes que no son de confianza también deben verificar la autenticidad de los mensajes, debe usar un esquema de firma digital.

Es probable que haya algo de soporte para ambos en las bibliotecas .Net. Miles proporcionó amablemente (como comentario) un enlace a la página web de MSDN para las funciones de la biblioteca .Net implementando un HMAC con clave usando el hash SHA1: http://msdn.microsoft.com/en-us/library/system.security.cryptography.hmacsha1.aspx.

+0

+1 HMAC. Las firmas digitales asimétricas sugeridas por la mayoría de las otras respuestas son excesivas para este problema. – Miles

+0

http://en.wikipedia.org/wiki/HMAC - http://msdn.microsoft.com/en-us/library/system.security.cryptography.hmacsha1.aspx – Miles

Cuestiones relacionadas