Raketenwilli: PHP-Funktion password_hash für Python

Beitrag lesen

(Vorab: Die Sache drängelt nicht…)

Ist zufällig mal jemand über eine Funktion, Klasse oder Libary gestolpert, mit der in Python Passwort-Hashes für PHP (und visa versa) erzeugt und verifiziert werden können?

Die hashlib und passlib hab ich gefunden, das Zeug erzeugt aber Passwörter, die mit $2b$ beginnen - die mag password_verify() von PHP nicht.

Hier mein Versuch aus dem tmp-Ordner (unten, class php_password), der aber auch nicht klug macht...

#!/usr/bin/python3
# -*- coding: utf-8 -*-

import hashlib
import base64
import random
import re

import passlib
import bcrypt


class password:

	def hash( password, hashmethod='sha256', rounds=6, saltLen=22 ):
		
		minRounds     = 5000
		minSaltLen    = 16
		unsafeMethods ={ 'md5', 'sha1', 'shake_128' }
		
		if not hashmethod in hashlib.algorithms_guaranteed:
			print ( "Fatal: Methode (2. Argument) ist nicht in ", hashlib.algorithms_guaranteed )
			exit( 1 )
		if hashmethod in unsafeMethods:
			print ( "Fatal: Methode (2. Argument) ist Liste unsicherer Methoden ", unsafeMethods )
			exit( 2 )
		
		if rounds < 10:
			rounds=10**rounds
		
		if rounds < minRounds:
			print ( "Fatal: Es ist keine gute Idee, den Hashvorgang weniger als " + str(minRounds)  + " mal durchzuführen." )
			exit( 4 )				
		if saltLen < minSaltLen:
			print ( "Fatal: Es ist keine gute Idee, eine Saltlänge unter " + str(minSaltLen)  + " zu benutzen." )
			exit( 4 )	
		
		chars='0123456789qwertzuiopasdfghjklyxcvbnmQWERTZUIOPASDFGHJKLYXCVBNM./'
		salt=''
		for i in range(saltLen):
			pos = random.randrange( len( chars ) )
			salt += chars[pos]
		
		hash = hashlib.pbkdf2_hmac(
			hashmethod,
			bytes(password,	encoding='utf-8'),
			bytes(salt,     encoding='utf-8'),
			int(rounds)
		)
		hash = str(base64.b64encode( hash ))[2:-1]
		hash=re.sub( '=+$', '', hash )
		return ( 
			'pbkdf2_hmac' 
			+ '_' 
			+ hashmethod 
			+ '_' 
			+ str(rounds) 
			+ '$' 
			+ salt
			+ '$'
			+ (hash)
		)

	def verify ( password, pwhash ):
		mod, salt, hash = pwhash.split('$')
		#print(mod.split('_')); exit()
		system1, system2, hashmethod,rounds = mod.split('_')
		if not hashmethod in hashlib.algorithms_available:
			print ( "Fatal: Methode '" + hashmethod + "' ist nicht in ", hashlib.algorithms_guaranteed )
		#testhash = hashlib.pbkdf2_hmac( hashmethod, bytes(password, encoding='utf-8'), bytes( salt, encoding='utf-8'), int(rounds) )
		testhash = hashlib.pbkdf2_hmac(
			hashmethod,
			bytes(password,	encoding='utf-8'),
			bytes(salt,     encoding='utf-8'),
			int(rounds )
		)
		testhash = str(base64.b64encode( testhash ))[2:-1]
		testhash=re.sub( '=+$', '', testhash )
		
		testhash =  str(
			mod
			+ '$' 
			+ salt
			+ '$'
			+ testhash
		)
		#print('hash:',pwhash)
		#print('test:',testhash)
		return testhash == pwhash

class php_password:
	def hash( password ):
		s = str (
			bcrypt.hashpw( bytes(password, 'utf-8'), bcrypt.gensalt() )
		)
		return s[2:-1]

	def verify( password, hash ):
		return bcrypt.checkpw( bytes(password, 'utf-8'), bytes(hash, 'ascii') )



print ("\n####################\nHashlib-Hashes\n####################")
hash = password.hash( 'hallo', 'sha512' )
print( hash )
if password.verify( 'hallo1', hash ):
	print('Hallo Boris: Du bist drin')
else:
	print('Nö')

print ("\n####################\nPHP-Hashes\n####################")

hash = php_password.hash('hallo')
print( hash )
if php_password.verify( 'hallo1', hash ):
	print('Hallo Boris: Auch mit PHP bist Du drin')
else:
	print('Nö')
exit(0)