In company we move some parts of the system from .NET to python. One of these parts is logging/authorization module. I need to implement in python CryptographyManager.CompareHash Method . It takes salted and hashed password from database and compares it with user input (plaintext). To do it I have to salt and hash user input and then check it with hashed password from database.
The password in the database was hashed by Microsoft Enterprise Library.Security.Cryptography
. Here more details:
Symmetric Crypto Providers: algorithmType="System.Security.Cryptography.AesManaged name="AES"
Hash Providers : algorithmType="System.Security.Cryptography.SHA256Managed saltEnabled="true" name="SHA256"
I found that password is slated in that way: Base64(salt + SHA256(salt + password))
. The salt is the first 16 bytes from the hashed password
What I am trying to do is get salt from hashed password in database and next hash and salt user input (plain text) to compare both.
Unfortunately, in the end there is no succes. Hashes are diffrent. Probably I am doning something wrong with de/encoding
My code looks like that:
import base64
import hashlib
hash = 'EwxBhfN0fM5Puv8/z+3/L50QvdU6BHFb4XQU9xtye/mOXJ8tBPc3tIyW7dEiZrvA'
password = 'some_plain_password'
#password = password.encode()
password = base64.b64decode(password)
#hash to byte
b_hash = base64.b64decode (hash)
print(b_hash)
#get salt, first 16 bytes
salt = b_hash[:15]
salt=base64.b64encode(salt)
print(salt)
m = hashlib.sha256()
m.update(salt)
m.update(password)
print(m.hexdigest())
It's a bit tricky to do this without an example plaintext and hash to verify the results, but your code should implement the algorithm you list in your question:
Base64(salt + SHA256(salt + password))
I think you want something like this:
import base64
import hashlib
hash = 'EwxBhfN0fM5Puv8/z+3/L50QvdU6BHFb4XQU9xtye/mOXJ8tBPc3tIyW7dEiZrvA'
salt = base64.b64decode(hash)[:16] # Use 16 here, not 15
password = 'some_plain_password'
# First let's do the SHA256(salt + password) part
m = hashlib.sha256()
m.update(salt)
m.update(password.encode('utf-8'))
# Now let's feed that into the Base64 part
new_hash = base64.encode(salt + m.digest())
My post is not 100% answer but more the end of the story. The problem is that there is no official source how works CryptographyManager.Compare/Create Hash I tried a lot of combinations with Base64(salt + SHA256(salt + password)) but without succes. Finally, I decide to rewrite C# code. If someone is looking for python code that is salting and hashing password and compare two hashes, below is my working example:
import base64
import hashlib
import os
class Hashing(object):
# base64( SHA256(password + salt) + salt)
# generate new salt (default 16 bytes_
def generate_new_salt(self, salt_ln=16):
self.new_salt = os.urandom(salt_ln)
print(f'new salt: {self.new_salt}')
return self.new_salt
# get salt from hash
def get_old_salt(self, input_hash, salt_ln=16):
self.old_salt = base64.b64decode(input_hash)[-salt_ln:]
print(f'old salt: {self.old_salt}')
return self.old_salt
# compute hash using parameters
def compute_hash(self, password, salt):
self.salt = salt
self.enc_password = password.encode()
# hashing SHA256(password + salt)
hash_object = hashlib.sha256(self.enc_password + salt)
# add salt to hash and encode to base64
hash_b64 = base64.b64encode(hash_object.digest() + salt)
print(f'new_hash: {hash_b64}')
return hash_b64
# create hash from new or old salt
def create_hash(self, password, salt_ln=16,old_salt=None):
if old_salt: #if old salt then use it
self.salt = old_salt
else: #else generate new salt
self.salt = Hashing().generate_new_salt(salt_ln)
hash = Hashing().compute_hash(password, self.salt)
return hash
# compare input hash with created using salt get from input
def compare_hashes(self, password, old_hash, salt_ln=16):
self.enc_password = password.encode()
#get salt from input hash
self.old_salt = Hashing().get_old_salt(old_hash, salt_ln)
#recreat input hash
re_hash = Hashing().create_new_hash(password,salt_ln, self.old_salt)
print(f'Compare: old_hash: {old_hash}')
print(f'Compare: new_hash: {re_hash}')
#compare
if re_hash.decode() == old_hash.decode():
return True
else:
return False
#code below is just for testing
NewSalt = Hashing().generate_new_salt()
Hash = Hashing().create_new_hash('pass')
OldSalt = Hashing().get_old_salt(Hash)
CompareHash = Hashing().compare_hashes('pass', Hash)
if CompareHash:
print('HASHES THE SAME')
else:
print('NOT THE SAME')
print(CompareHash)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.