Сравните соленые хешированные пароли в Python для авторизации - PullRequest
2 голосов
/ 26 января 2020

В компании мы перемещаем некоторые части системы с. NET на python. Одна из этих частей - модуль регистрации / авторизации. Мне нужно реализовать в python CryptographyManager.CompareHa sh Method . Он берет соленый и хешированный пароль из базы данных и сравнивает его с пользовательским вводом (открытым текстом). Для этого мне нужно подсчитать и ввести sh пользовательский ввод, а затем проверить его с помощью хешированного пароля из базы данных.

Пароль в базе данных был хэширован Microsoft Enterprise Library.Security.Cryptography. Вот более подробная информация:

Symmetri c Провайдеры шифрования: gorithType = "System.Security.Cryptography.AesManaged name =" AES "

Ха sh Провайдеры :gorithType = "System.Security.Cryptography.SHA256Managed saltEnabled =" true "name =" SHA256 "

Я обнаружил, что пароль назначается таким образом: Base64(salt + SHA256(salt + password)). Соль - это первые 16 байтов из хешированного пароля

Я пытаюсь получить соль из хешированного пароля в базе данных и следующий га sh и солитный ввод пользователя (простой текст) для сравнения обоих.

К сожалению, в итоге нет успеха. Хеши разные. Возможно, я что-то не так с де / кодированием

Мой код выглядит так:

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())

Ответы [ 2 ]

1 голос
/ 26 января 2020

Это немного сложно сделать без примера открытого текста и ха sh, чтобы проверить результаты, но ваш код должен реализовать алгоритм, который вы перечислили в своем вопросе:

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())
0 голосов
/ 29 января 2020

Мой пост - не 100% ответ, а скорее конец истории. Проблема в том, что нет официального источника, как работает CryptographyManager.Compare/Create Ha sh Я перепробовал много комбинаций с Base64 (соль + SHA256 (соль + пароль)), но без успеха. Наконец, я решил переписать код 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)
...