[英]Compare salted hashed passwords in Python for authorisation
在公司中,我们将系统的某些部分从 .NET 迁移到 Python。 这些部分之一是日志/授权模块。 我需要在 python CryptographyManager.CompareHash Method 中实现。 它从数据库中获取加盐和散列的密码,并将其与用户输入(明文)进行比较。 为此,我必须对用户输入进行加盐和哈希处理,然后使用数据库中的哈希密码进行检查。
数据库中的密码由 Microsoft Enterprise Library.Security.Cryptography
散列。 这里有更多细节:
对称加密提供程序: algorithmType="System.Security.Cryptography.AesManaged name="AES"
哈希提供程序: algorithmType="System.Security.Cryptography.SHA256Managed saltEnabled="true" name="SHA256"
我发现密码是以这种方式指定的: Base64(salt + SHA256(salt + password))
。 盐是散列密码的前 16 个字节
我想要做的是从数据库中的散列密码和下一个散列和盐用户输入(纯文本)中获取盐分来比较两者。
不幸的是,最终没有成功。 哈希是不同的。 可能我在解码/编码方面做错了什么
我的代码看起来像这样:
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())
在没有示例明文和哈希来验证结果的情况下执行此操作有点棘手,但是您的代码应该实现您在问题中列出的算法:
Base64(salt + SHA256(salt + password))
我想你想要这样的东西:
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())
我的帖子不是 100% 的答案,而是故事的结局。 问题是没有官方来源 CryptographyManager.Compare/Create Hash 我尝试了很多 Base64(salt + SHA256(salt + password)) 的组合,但没有成功。 最后,我决定重写 C# 代码。 如果有人正在寻找对密码进行加盐和散列处理的 Python 代码并比较两个散列值,下面是我的工作示例:
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)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.