We have a current application in which user login credentials are stored in a SQL Server database. They are stored primarily as a text username, password hash and associated salt for this hash.
All of them were created by built-in functions in the ASP.NET membership / role system. Here is the line for the user named "joe" and the password is "password":
Joe, kDP0Py2QwEdJYtUX9cJABg ==, OJF6H4KdxFLgLu + oTDNFodCEfMA =
I threw this stuff into a CSV file, and I'm trying to load it into a Django-friendly format that stores its passwords in this format:
[algo] $ [salt] $ [hash]
If the salt is a simple string and the hash is the SHA1 hexadecimal digest.
Until now, I could verify that ASP stores these hashes and salts in base64 format. These values above are decoded into binary strings.
We used a reflector to find out how ASP authenticates against these values:
internal string EncodePassword(string pass, int passwordFormat, string salt) { if (passwordFormat == 0) { return pass; } byte[] bytes = Encoding.Unicode.GetBytes(pass); byte[] src = Convert.FromBase64String(salt); byte[] dst = new byte[src.Length + bytes.Length]; byte[] inArray = null; Buffer.BlockCopy(src, 0, dst, 0, src.Length); Buffer.BlockCopy(bytes, 0, dst, src.Length, bytes.Length); if (passwordFormat == 1) { HashAlgorithm algorithm = HashAlgorithm.Create(Membership.HashAlgorithmType); if ((algorithm == null) && Membership.IsHashAlgorithmFromMembershipConfig) { RuntimeConfig.GetAppConfig().Membership.ThrowHashAlgorithmException(); } inArray = algorithm.ComputeHash(dst); } else { inArray = this.EncryptPassword(dst); } return Convert.ToBase64String(inArray); }
Eseentially, extracts salt from the database and b64 decodes it into binary representation. He makes "GetBytes" on a raw password, and then he combines them, first with salt.
Then it runs the SHA1 algorithm in this new line, base64 encodes it and compares it with the value stored in the database.
I tried to write some code to try to reproduce these hashes in Python, and I am failing. I cannot use them in Django until I can understand how this translates. This is how I test:
import hashlib from base64 import b64decode, b64encode b64salt = "kDP0Py2QwEdJYtUX9cJABg==" b64hash = "OJF6H4KdxFLgLu+oTDNFodCEfMA=" binsalt = b64decode(b64salt) password_string = 'password' m1 = hashlib.sha1()
I am wondering if anyone can see any flaws in my approach or suggest an alternative method. Perhaps you can take the above algorithms and a well-known password and salt and create a hash in your system?