简体   繁体   English

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

[英]Compare salted hashed passwords in Python for authorisation

In company we move some parts of the system from .NET to python.在公司中,我们将系统的某些部分从 .NET 迁移到 Python。 One of these parts is logging/authorization module.这些部分之一是日志/授权模块。 I need to implement in python CryptographyManager.CompareHash Method .我需要在 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 .数据库中的密码由 Microsoft Enterprise Library.Security.Cryptography散列。 Here more details:这里有更多细节:

Symmetric Crypto Providers: algorithmType="System.Security.Cryptography.AesManaged name="AES"对称加密提供程序: algorithmType="System.Security.Cryptography.AesManaged name="AES"

Hash Providers : algorithmType="System.Security.Cryptography.SHA256Managed saltEnabled="true" name="SHA256"哈希提供程序: algorithmType="System.Security.Cryptography.SHA256Managed saltEnabled="true" name="SHA256"

I found that password is slated in that way: Base64(salt + SHA256(salt + password)) .我发现密码是以这种方式指定的: Base64(salt + SHA256(salt + password)) The salt is the first 16 bytes from the hashed password盐是散列密码的前 16 个字节

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.我的帖子不是 100% 的答案,而是故事的结局。 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.问题是没有官方来源 CryptographyManager.Compare/Create Hash 我尝试了很多 Base64(salt + SHA256(salt + password)) 的组合,但没有成功。 Finally, I decide to rewrite C# code.最后,我决定重写 C# 代码。 If someone is looking for python code that is salting and hashing password and compare two hashes, below is my working example:如果有人正在寻找对密码进行加盐和散列处理的 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