How to reproduce System.Security.Cryptography.SHA1Managed result in Python

后端 未结 5 678
梦毁少年i
梦毁少年i 2021-01-17 03:07

Here\'s the deal: I\'m moving a .NET website to Python. I have a database with passwords hashed using the System.Security.Cryptography.SHA1Managed utility.

I\'m cre

5条回答
  •  广开言路
    2021-01-17 03:39

    Thanks Gareth Stephenson! your answer had all the answers I needed. I was getting completely lost with this. I needed to upgrade a legacy module that was using this enterprise library, but there were so many problems with compiling I couldn't debug the code. Keeping the code opened a zillion other problems with dependencies and public key token mismatches / versions. So I re-wrote the functions needed based on Gareth's answer. I eventually found the encryption used in the config file. This can be in the app.config (in my case), web.config or other config somewhere:

    
    
      
    
    

    The code I wrote is:

    //Because of the random salt added, each time you hash a password it will create a new result.
        public static string GetHashedValue(string password)
        {
            //this will create a new hash?
            //Hashed Password Formula: Base64(salt + Sha1(salt + value))
            var crypto = new SHA1CryptoServiceProvider();
            byte[] saltBytes = new byte[16];
            RandomNumberGenerator.Create().GetBytes(saltBytes); 
    
            byte[] checkPasswordBytes = Encoding.Unicode.GetBytes(password);
            byte[] tempResult = crypto.ComputeHash(saltBytes.Concat(checkPasswordBytes).ToArray()); //ComputeHash(salt + value)
            byte[] resultBytes = saltBytes.Concat(tempResult).ToArray();  //salt + ComputeHash(salt + value)
    
            return Convert.ToBase64String(resultBytes);
        }
    

    and to check the validity of a password:

    public static bool IsPasswordValid(string passwordToCheck, string savedPassword)
        {
            bool retVal = false;
    
            var crypto = new SHA1CryptoServiceProvider();
    
            //get the salt, which is part of the saved password. These are the first 16 bytes.
            byte[] storedPasswordBytes = Convert.FromBase64String(savedPassword);
            byte[] saltBytes = new byte[16];
            Array.Copy(storedPasswordBytes, saltBytes, 16);
    
            //hash the password that you want to check with the same salt and the same algoritm:
            byte[] checkPasswordBytes = Encoding.Unicode.GetBytes(passwordToCheck);
            byte[] tempResult = crypto.ComputeHash(saltBytes.Concat(checkPasswordBytes).ToArray()); //ComputeHash(salt + value)
            byte[] resultBytes = saltBytes.Concat(tempResult).ToArray();  //salt + ComputeHash(salt + value)
            string resultString = Convert.ToBase64String(resultBytes);
    
            if (savedPassword == resultString)
            {
                retVal = true;
            }
    
            return retVal;
        }
    

    And that just before I thought I would have to reset all my customers' passwords... I hope this will safe someone else as well one day!

提交回复
热议问题