问题
I'm working on a Python script to create hashed strings from an existing system similar to that of ASP.NET's MembershipProvider. Using Python, is there a way to take a hexadecimal string and convert it back to a binary and then do a base64 encoding, somehow treating the original string as Unicode. Let's try some code. I'm looking to re-encode a hashed password so that the hashes would be equal in Python and ASP.NET/C#:
import base64
import sha
import binascii
def EncodePassword(password):
# strings are currently stored as hex
hex_hashed_password = sha.sha(password).hexdigest()
# attempt to convert hex to base64
bin_hashed_password = binascii.unhexlify(hex_hashed_password)
return base64.standard_b64encode(bin_hashed_password)
print EncodePassword("password")
# W6ph5Mm5Pz8GgiULbPgzG37mj9g=
The ASP.NET MembershipProvider users this method to encode:
static string EncodePassword(string pass)
{
byte[] bytes = Encoding.Unicode.GetBytes(pass);
//bytes = Encoding.ASCII.GetBytes(pass);
byte[] inArray = null;
HashAlgorithm algorithm = HashAlgorithm.Create("SHA1");
inArray = algorithm.ComputeHash(bytes);
return Convert.ToBase64String(inArray);
}
string s = EncodePassword("password");
// 6Pl/upEE0epQR5SObftn+s2fW3M=
That doesn't match. But, when I run it with the password encoded with ASCII encoding, it matches, so the Unicode part of the .NET method is what's the difference.
W6ph5Mm5Pz8GgiULbPgzG37mj9g=
Is there a way in the python script to get an output to match the default .NET version?
回答1:
This is the trick:
Encoding.Unicode
“Unicode” encoding is confusing Microsoft-speak for UTF-16LE (specifically, without any BOM). Encode the string to that before hashing and you get the right answer:
>>> import hashlib
>>> p= u'password'
>>> hashlib.sha1(p.encode('utf-16le')).digest().encode('base64')
'6Pl/upEE0epQR5SObftn+s2fW3M=\n'
来源:https://stackoverflow.com/questions/1456770/can-python-encode-a-string-to-match-asp-net-membership-providers-encodepassword