繁体   English   中英

比较 Python 中的加盐散列密码以进行授权

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM