2010-05-13 6 views
4

Aujourd'hui, j'ai déplacé mon application Web vers .net 4.0 et Forms Auth ne fonctionnait plus. Après plusieurs heures de creuser dans mon SqlMembershipProvider (version simplifiée de SqlMembershipProvider intégré), j'ai trouvé que le hachage HMACSHA256 n'est pas cohérent. C'est la méthode de cryptage:Erreur de cryptage incorrecte dans .NET 4.0

internal string EncodePassword(string pass, int passwordFormat, string salt) 
{ 
    if (passwordFormat == 0) // MembershipPasswordFormat.Clear 
     return pass; 

    byte[] bIn = Encoding.Unicode.GetBytes(pass); 
    byte[] bSalt = Convert.FromBase64String(salt); 
    byte[] bAll = new byte[bSalt.Length + bIn.Length]; 
    byte[] bRet = null; 

    Buffer.BlockCopy(bSalt, 0, bAll, 0, bSalt.Length); 
    Buffer.BlockCopy(bIn, 0, bAll, bSalt.Length, bIn.Length); 
    if (passwordFormat == 1) 
    { // MembershipPasswordFormat.Hashed 
     HashAlgorithm s = HashAlgorithm.Create(Membership.HashAlgorithmType); 
     bRet = s.ComputeHash(bAll); 
    } else 
    { 
     bRet = EncryptPassword(bAll); 
    } 

    return Convert.ToBase64String(bRet); 
} 

Passer le même mot de passe et sel deux fois donne des résultats différents !!! Il fonctionnait parfaitement dans .NET 3.5

Quelqu'un est-il au courant de tout changement de rupture, ou est-ce un bug connu?

MISE À JOUR: Quand je précise SHA512 que l'algorithme de hachage, tout fonctionne très bien, donc je ne crois que c'est un bogue dans la mise en œuvre de l'algorithme de hachage HMACSHA256 dans .NET 4.0

Merci! Andrey

Répondre

2

Je crois qu'il ya eu une certaine sécurité dans les changements liés 4.0 .net un coup d'oeil à ce ...

http://www.asp.net/(S(ywiyuluxr3qb2dfva1z5lgeg))/learn/whitepapers/aspnet4/breaking-changes

La première chose évidente qui colle est ce ...

par défaut est maintenant algorithme SHA HMACSHA256

ASP.NET utilise le chiffrement et algorithmes de hachage pour aider à sécuriser les données tels que les cookies d'authentification des formulaires et l'état d'affichage. Par défaut, ASP.NET 4 utilise maintenant l'algorithme HMACSHA256 pour les opérations de hachage sur les cookies et affiche l'état . Les versions antérieures d'ASP.NET utilisaient l'ancien algorithme HMACSHA1.

Vos applications peuvent être affectées si vous exécutez mélangé ASP.NET 2.0/ASP.NET 4 environnements où des données telles que les formulaires cookies d'authentification doivent travailler versions Framework across.NET. Pour configurer une application Web ASP.NET 4 utiliser l'algorithme de HMACSHA1 plus, ajouter le paramètre suivant dans le fichier web.config:

 <machineKey validation="SHA1" /> 

Avez-vous définir explicitement votre algorithme de hachage ou tout simplement laisser asp.net décide ... s'il utilise une valeur par défaut différente, il peut s'agir simplement de saisir un ancien algorithme de hachage au hasard, car celui qui est défini n'est plus supporté. Cela dit, M $ peut avoir retiré celui que vous utilisez, ce qui peut être la cause, bugger .... Je viens de réaliser que j'ai besoin de tester mon CMS ... cela ne m'est pas venu à l'esprit .

Merci pour les heads up, j'espère que mes pensées nous aideront tous les deux !!!

2

J'ai également rencontré ce problème.

Dans mon cas, l'objectif final était de pouvoir définir dynamiquement connectionString (au lieu de coder en dur dans le fichier web.config). Je l'ai fait en téléchargeant le code source que MS a mis pour l'ASP.NET fournisseurs et en modifiant certaines des fonctionnalités internes pour obtenir la chaîne de connexion. Cependant, tout cela était pour .NET 2.0 et ressemble exactement au code affiché par Andrey ci-dessus. Une fois que tout a été mis en place, j'ai remarqué que je ne pouvais pas me connecter à mon site Web. Donc, après avoir cherché, j'ai trouvé ce post. Merci!

Je suis allé de l'avant et téléchargé le code .NET Framework 4.0 et (si quelqu'un veut savoir) voici la nouvelle version de la méthode EncodePassword. Je prévois de copier ceci dans mon ancienne version de SqlMembershipProvider afin que je puisse utiliser les nouvelles méthodes de cryptage et pouvoir me connecter à nouveau à mon site Web ASP.NET 4.0!

private string EncodePassword(string pass, int passwordFormat, string salt) 
    { 
     if (passwordFormat == 0) // MembershipPasswordFormat.Clear 
      return pass; 

     byte[] bIn = Encoding.Unicode.GetBytes(pass); 
     byte[] bSalt = Convert.FromBase64String(salt); 
     byte[] bRet = null; 

     if (passwordFormat == 1) 
     { // MembershipPasswordFormat.Hashed 
      HashAlgorithm hm = GetHashAlgorithm(); 
      if (hm is KeyedHashAlgorithm) { 
       KeyedHashAlgorithm kha = (KeyedHashAlgorithm) hm; 
       if (kha.Key.Length == bSalt.Length) { 
        kha.Key = bSalt; 
       } else if (kha.Key.Length < bSalt.Length) { 
        byte[] bKey = new byte[kha.Key.Length]; 
        Buffer.BlockCopy(bSalt, 0, bKey, 0, bKey.Length); 
        kha.Key = bKey; 
       } else { 
        byte[] bKey = new byte[kha.Key.Length]; 
        for (int iter = 0; iter < bKey.Length;) { 
         int len = Math.Min(bSalt.Length, bKey.Length - iter); 
         Buffer.BlockCopy(bSalt, 0, bKey, iter, len); 
         iter += len; 
        } 
        kha.Key = bKey; 
       } 
       bRet = kha.ComputeHash(bIn); 
      } 
      else { 
       byte[] bAll = new byte[bSalt.Length + bIn.Length]; 
       Buffer.BlockCopy(bSalt, 0, bAll, 0, bSalt.Length); 
       Buffer.BlockCopy(bIn, 0, bAll, bSalt.Length, bIn.Length); 
       bRet = hm.ComputeHash(bAll); 
      } 
     } else { 
      byte[] bAll = new byte[bSalt.Length + bIn.Length]; 
      Buffer.BlockCopy(bSalt, 0, bAll, 0, bSalt.Length); 
      Buffer.BlockCopy(bIn, 0, bAll, bSalt.Length, bIn.Length); 
      bRet = EncryptPassword(bAll, _LegacyPasswordCompatibilityMode); 
     } 

     return Convert.ToBase64String(bRet); 
    } 

Edit: Tentative de copier ce une méthode dans l'ancienne version du SqlMembershipProvider était une mauvaise idée. Trop a changé. :(