5 votes

ASP.NET MembershipProvider -- Comment procède-t-il exactement au cryptage ?

J'ai besoin de comprendre les détails de la manière dont MembershipProvider effectue le cryptage :

  1. Quel algorithme utilise-t-il ?
  2. Y a-t-il un prétraitement ou un post-traitement de l'encodage base64 ?
  3. Y a-t-il quelque chose qu'il fait en plus de l'algorithme standard qu'il utilise ?

Compte tenu d'un mot de passe en texte clair à crypter, veuillez m'expliquer les étapes exactes qui permettent d'obtenir le mot de passe crypté final qui est renvoyé.

Je pense que voir le code source permettrait de répondre à mes questions, mais je n'ai pas réussi à le trouver en ligne. Je n'ai trouvé que cette documentation qui ne fournit pas de détails sur la mise en œuvre.

Merci pour toute information !

8voto

Charlino Points 11217

Vous trouverez ci-dessous le code que vous voulez / dont vous avez besoin... c'est un peu un labyrinthe pour y arriver, donc pour bien comprendre, je vous recommande de faire ce qui suit :

  • Installer ReSharper
    [Facultatif] Installer dotPeek
  • Ecrivez le code suivant n'importe où :
    var dummyMembershipProvider = new SqlMembershipProvider();
    dummyMembershipProvider.ChangePassword("userName", "oldPassword", "newPassword");
  • Ctrl + clic gauche (aller à la définition) sur ChangePassword
  • C'est ainsi que vous commencerez votre voyage dans le terrier du lapin... il devrait ressembler à ceci :
    SqlMembershipProvider.ChangePassword
    SqlMembershipProvider.EncodePassword
    MembershipProvider.EncryptPassword
    IMembershipAdapter.EncryptOrDecryptData
    MembershipAdapter.EncryptOrDecryptData
    MachineKeySection.EncryptOrDecryptData
  • Achetez ReSharper parce que vous vous rendez compte que vous ne pouvez plus vous en passer

Quoi qu'il en soit, voici le fichier MachineKeySection.EncryptOrDecryptData :

public sealed class MachineKeySection : ConfigurationSection
{
    internal static byte[] EncryptOrDecryptData(bool fEncrypt, byte[] buf, byte[] modifier, int start, int length,
                                                bool useValidationSymAlgo, bool useLegacyMode, IVType ivType)
    {
        EnsureConfig(); 

        if (useLegacyMode) 
            useLegacyMode = _UsingCustomEncryption; // only use legacy mode for custom algorithms 

        System.IO.MemoryStream ms = new System.IO.MemoryStream(); 
        ICryptoTransform oDesEnc = GetCryptoTransform(fEncrypt, useValidationSymAlgo, useLegacyMode);
        CryptoStream cs = new CryptoStream(ms, oDesEnc, CryptoStreamMode.Write);

        // DevDiv Bugs 137864: Add Random or Hashed IV to beginning of data to be encrypted. 
        // IVType.None is used by MembershipProvider which requires compatibility even in SP2 mode.
        bool createIV = ((ivType != IVType.None) && (CompatMode > MachineKeyCompatibilityMode.Framework20SP1)); 

        if (fEncrypt && createIV)
        { 
            byte[]  iv       = null;
            int     ivLength = (useValidationSymAlgo ? _IVLengthValidation : _IVLengthDecryption);
            switch (ivType)
            { 
            case IVType.Hash:
                iv = GetIVHash(buf, ivLength); 
                break; 
            case IVType.Random:
                iv = new byte[ivLength]; 
                RandomNumberGenerator.GetBytes(iv);
                break;
            }
            Debug.Assert(iv != null, "Invalid value for IVType: " + ivType.ToString("G")); 
            cs.Write(iv, 0, iv.Length);
        } 

        cs.Write(buf, start, length);
        if (fEncrypt && modifier != null) 
        {
            cs.Write(modifier, 0, modifier.Length);
        }

        cs.FlushFinalBlock();
        byte[] paddedData = ms.ToArray(); 
        byte[] bData; 
        cs.Close();
        ReturnCryptoTransform(fEncrypt, oDesEnc, useValidationSymAlgo, useLegacyMode); 

        // DevDiv Bugs 137864: Strip Random or Hashed IV from beginning of unencrypted data
        if (!fEncrypt && createIV)
        { 
            // strip off the first bytes that were either random bits or a hash of the original data
            // either way it is always equal to the key length 
            int ivLength = (useValidationSymAlgo ? _IVLengthValidation : _IVLengthDecryption); 
            int bDataLength = paddedData.Length - ivLength;

            // valid if the data is long enough to have included the padding
            if (bDataLength >= 0)
            {
                bData = new byte[bDataLength]; 
                // copy from the padded data to non-padded buffer bData.
                // dont bother with copy if the data is entirely the padding 
                if (bDataLength > 0) 
                {
                    Buffer.BlockCopy(paddedData, ivLength, bData, 0, bDataLength); 
                }
            }
            else
            { 
                // data is not padded because it is not long enough
                bData = paddedData; 
            } 
        }
        else 
        {
            bData = paddedData;
        }

        if (!fEncrypt && modifier != null && modifier.Length > 0)
        { 
            for(int iter=0; iter<modifier.Length; iter++) 
                if (bData[bData.Length - modifier.Length + iter] != modifier[iter])
                    throw new HttpException(SR.GetString(SR.Unable_to_validate_data)); 
            byte[] bData2 = new byte[bData.Length - modifier.Length];
            Buffer.BlockCopy(bData, 0, bData2, 0, bData2.Length);
            bData = bData2;
        } 
        return bData;
    } 
}

0voto

Erik Funkenbusch Points 53436

Le code source des fournisseurs d'adhésion est disponible auprès de Microsoft. Scott Guthrie a publié un blog à ce sujet il y a quelques années.

http://weblogs.asp.net/scottgu/archive/2006/04/13/442772.aspx

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X