2009-04-02 12 views
6

J'ai un message que je me passe et qui sera sujet à des attaques de l'homme du milieu. À cause de cela, je suis préoccupé par l'intégrité du message maintenu entre le moment où je l'envoie et le moment où je le reçois.Maintien de l'intégrité des messages

Il devrait être supposé qu'une fois que je m'enverrai le message, aucune information sur le message envoyé ne sera disponible pour moi dans le futur. Le message est complètement autonome. À cette fin, je sais que devrait hacher le contenu du message et comparer les hachages avant d'envoyer le message, et après avoir envoyé le message, si elles diffèrent, le message a été falsifié. Bien sûr, si l'homme-dans-le-milieu sait que le hachage est vraiment juste le hachage du contenu du message, tel quel, puis parce que le message est autonome, il peut simplement créer de nouveaux contenus et appliquer le même algorithme de hachage au contenu. La question est de savoir jusqu'où dois-je aller pour randomiser le contenu du message lors de la génération du hachage? Quand atteint-il le point de rendements décroissants?

Dans ce scénario, j'ai un ensemble de paires clé/valeur. À cette fin, les étapes que je sais que je dois prendre sont les suivantes:

  1. Ajouter un sel au message. Le sel est un secret pour le reste du monde. Il est attaché au contenu du message avant le hachage.
  2. Commandez les paires clé/valeur de manière cohérente avant de générer le hachage.
  3. Bien que pas directement pertinent, un horodatage va être ajouté au contenu de chaque message avant le hachage, pour éviter les attaques de rejeu.

Ce sont les étapes facultatives que j'envisage:

  1. Transformer les clés avant de les commander. J'ai envisagé de les inverser, puis de les commander en fonction du nombre/clé.
  2. Jouer avec les séparateurs qui séparent les paires clé/valeur (à la fois pour le séparateur de la clé/valeur et le séparateur pour la paire).

NOTE

confidentialité du message est pas une exigence ici, donc je ne suis pas à la recherche pour le chiffrement. Les valeurs doivent être être transmises en texte clair.

Enfin, quels algorithmes de hachage dois-je éviter?


Spécificités

I ont un site ASP.NET MVC que j'ai un contrôleur qui traite la validation d'entrée et de persistance.

Si (basé sur une heuristique, ce n'est pas important) l'entrée est considérée comme une tentative automatique de spam, un modèle de IDictionary<string, string> est créé avec les valeurs d'entrée et un ViewResult est envoyé à une page CAPTCHA générale.Dans cette vue, sous la forme qui contient le contrôle CAPTCHA, le contenu du IDictionary<string, string> sera écrit dans des champs de saisie masqués et l'action du formulaire sera la même action que celle à laquelle le contenu a été initialement envoyé. De cette façon, MVC peut récupérer les valeurs lorsque le formulaire est soumis à nouveau. C'est pour cette raison que je ne peux pas crypter les paires clé/valeur (ou peut-être que je peux et devrait, dites-moi pourquoi et comment!).

Bien sûr, j'ai besoin d'ajouter une valeur supplémentaire, qui contient le contenu du message haché. Si cette valeur est présente, le contrôleur vérifiera que l'intégrité du message est maintenue et permettra à l'entrée d'être conservée si elle l'a été.

Solution

J'ai opté pour aller avec la classe SignedCms dans l'espace de noms System.Security.Cyrptography.Pkcs, qui représente la signging et la vérification de la CMS/PKCS # 7 messages.

Pour élaborer, j'ai créé un certificat auto-émis avec MakeCert.exe puis dans mon code, je donne l'exemple ici pour signer numériquement les données:

http://blogs.msdn.com/shawnfa/archive/2006/02/27/539990.aspx

Maintenant, il devrait il s'agit de sécuriser le mot de passe sur la clé privée exportée, ainsi que la sécurité sur le serveur, ce qui en fait moins de programmation.

Je vais devoir ajouter une clé supplémentaire pour l'horodatage des attaques de relecture, mais ce ne sera pas trop difficile. La réponse va à Kalium, pas pour son initial post, mais pour ses commentaires de suivi qui ont montré la voie aux signatures numériques, et finalement ma découverte de la façon de les utiliser dans .NET.

Merci à tous ceux qui ont contribué.

Répondre

6

Je pense que PGP/GPG est ce que vous voulez ici.

+0

@Kalium: Non, la confidentialité des messages n'est pas un problème et c'est un peu exagéré. En fait, la transparence des messages est une exigence. – casperOne

+1

C'est probablement la meilleure option pour assurer l'intégrité des messages. Vous n'avez pas besoin de le crypter, il suffit de le signer. Vous pouvez même envoyer la clé publique avec. – Kalium

+0

@Kalium: À cette fin, avez-vous des liens vers de bonnes ressources PGP/GPG dans .NET? Aussi, qu'en est-il du problème du "secret partagé"? Est-ce que le fait de signer le hachage avec une clé asymétrique fait de la clé privée le secret, et annule le besoin d'organiser différemment les données à hacher? – casperOne

1

Vous voulez un Digitally Signed message. En utilisant GPG vous pouvez signer le message sans le chiffrer. Mais personne ne sera capable de l'altérer, car ils ne peuvent pas générer le hachage - seulement vous pouvez parce que le hachage utilise votre clé privée.

0

Vous devez probablement signer numériquement le message (par conséquent, PGP/GPG recommandé par Kalium est pertinent en tant qu'option). Tout hachage pur que vous pouvez créer peut être recréé par l'attaquant. La signature numérique - en utilisant votre clé de signature privée pour que votre clé publique puisse être utilisée pour la vérifier - est la solution. Tout le reste est un exercice futile.

0

En supposant que vous ne pouvez pas passer des informations sur un canal « sécurisé » (à savoir le hachage) voici comment vous le faire:

  1. Hash le message, signe alors le hachage avec une clé privée. Incluez le hachage signé dans le message.
  2. Lorsque vous recevez le message, utilisez la clé publique pour déchiffrer le hachage signé et vérifiez qu'il correspond au hachage réel du message.

Un attaquant ne pourrait pas "simuler" un message, car il aurait besoin de votre clé privée pour crypter son nouveau hachage.

Comme d'autres l'ont mentionné, cela est tout simplement la signature numérique à la vanille simple et peut être manipulé par quelque chose comme PGP/GPG

2

L'approche la plus directe pour permettre à votre application pour vérifier que ses propres messages n'ont pas été falsifié serait d'utiliser un code d'authentification de hachage par clé. Le message est envoyé en clair, mais il inclut également un hachage pour empêcher toute altération. Le hachage dépend à la fois du contenu du message et d'une clé secrète. L'homme au milieu ne peut pas forger un hachage sur un message modifié sans connaître la clé. Puisque votre application crée et vérifie les messages, elle n'a jamais besoin de divulguer la clé secrète.

Je recommande en particulier la mise en œuvre décrite dans le document RFC-2104 http://www.ietf.org/rfc/rfc2104.txt car elle a été soigneusement étudiée pour éviter la plupart des pièges possibles.

Si les parties doivent également vérifier l'authenticité des messages, vous devez utiliser un schéma de signature numérique.

Il existe probablement un certain support pour les deux dans les bibliothèques .Net. Miles a utilement fourni (sous forme de commentaire) un lien vers la page Web MSDN pour les fonctions de la bibliothèque .Net implémentant un HMAC à clé utilisant le hachage SHA1: http://msdn.microsoft.com/en-us/library/system.security.cryptography.hmacsha1.aspx.

+0

+1 HMAC. Les signatures numériques asymétriques suggérées par la plupart des autres réponses sont exagérées pour ce problème. – Miles

+0

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