<s> import base64 <EOL> import hmac <EOL> import hashlib <EOL> import logging <EOL> import bcrypt <EOL> from django . conf import settings <EOL> from django . contrib . auth . hashers import ( BCryptPasswordHasher , <EOL> BasePasswordHasher , mask_hash ) <EOL> from django . utils . crypto import constant_time_compare <EOL> from django . utils . encoding import smart_str <EOL> from django . utils . datastructures import SortedDict <EOL> log = logging . getLogger ( '<STR_LIT>' ) <EOL> algo_name = lambda hmac_id : '<STR_LIT>' . format ( hmac_id . replace ( '<STR_LIT:->' , '<STR_LIT:_>' ) ) <EOL> def get_hasher ( hmac_id ) : <EOL> """<STR_LIT>""" <EOL> dash_hmac_id = hmac_id . replace ( '<STR_LIT:_>' , '<STR_LIT:->' ) <EOL> class BcryptHMACPasswordHasher ( BCryptPasswordHasher ) : <EOL> algorithm = algo_name ( hmac_id ) <EOL> rounds = getattr ( settings , '<STR_LIT>' , <NUM_LIT:12> ) <EOL> def encode ( self , password , salt ) : <EOL> shared_key = settings . HMAC_KEYS [ dash_hmac_id ] <EOL> hmac_value = self . _hmac_create ( password , shared_key ) <EOL> bcrypt_value = bcrypt . hashpw ( hmac_value , salt ) <EOL> return '<STR_LIT>' . format ( <EOL> self . algorithm , <EOL> bcrypt_value , <EOL> dash_hmac_id ) <EOL> def verify ( self , password , encoded ) : <EOL> algo_and_hash , key_ver = encoded . rsplit ( '<STR_LIT:$>' , <NUM_LIT:1> ) <EOL> try : <EOL> shared_key = settings . HMAC_KEYS [ key_ver ] <EOL> except KeyError : <EOL> log . info ( '<STR_LIT>' . format ( key_ver ) ) <EOL> return False <EOL> bc_value = '<STR_LIT>' . format ( algo_and_hash . split ( '<STR_LIT:$>' , <NUM_LIT:1> ) [ <NUM_LIT:1> ] ) <EOL> hmac_value = self . _hmac_create ( password , shared_key ) <EOL> return bcrypt . hashpw ( hmac_value , bc_value ) == bc_value <EOL> def _hmac_create ( self , password , shared_key ) : <EOL> """<STR_LIT>""" <EOL> hmac_value = base64 . b64encode ( hmac . new ( <EOL> smart_str ( shared_key ) , <EOL> smart_str ( password ) , <EOL> hashlib . sha512 ) . digest ( ) ) <EOL> return hmac_value <EOL> return BcryptHMACPasswordHasher <EOL> if not settings . HMAC_KEYS : <EOL> raise ImportError ( '<STR_LIT>' ) <EOL> for hmac_key in settings . HMAC_KEYS . keys ( ) : <EOL> hmac_id = hmac_key . replace ( '<STR_LIT:->' , '<STR_LIT:_>' ) <EOL> globals ( ) [ algo_name ( hmac_id ) ] = get_hasher ( hmac_id ) <EOL> class BcryptHMACCombinedPasswordVerifier ( BCryptPasswordHasher ) : <EOL> """<STR_LIT>""" <EOL> algorithm = '<STR_LIT>' <EOL> rounds = getattr ( settings , '<STR_LIT>' , <NUM_LIT:12> ) <EOL> def encode ( self , password , salt ) : <EOL> """<STR_LIT>""" <EOL> raise NotImplementedError ( ) <EOL> def verify ( self , password , encoded ) : <EOL> algo_and_hash , key_ver = encoded . rsplit ( '<STR_LIT:$>' , <NUM_LIT:1> ) <EOL> try : <EOL> shared_key = settings . HMAC_KEYS [ key_ver ] <EOL> except KeyError : <EOL> log . info ( '<STR_LIT>' . format ( key_ver ) ) <EOL> algorithm , data = encoded . split ( '<STR_LIT:$>' , <NUM_LIT:1> ) <EOL> return constant_time_compare ( data , bcrypt . hashpw ( password , data ) ) <EOL> bc_value = '<STR_LIT>' . format ( algo_and_hash . split ( '<STR_LIT:$>' , <NUM_LIT:1> ) [ <NUM_LIT:1> ] ) <EOL> hmac_value = self . _hmac_create ( password , shared_key ) <EOL> return bcrypt . hashpw ( hmac_value , bc_value ) == bc_value <EOL> def _hmac_create ( self , password , shared_key ) : <EOL> """<STR_LIT>""" <EOL> hmac_value = base64 . b64encode ( hmac . new ( <EOL> smart_str ( shared_key ) , <EOL> smart_str ( password ) , <EOL> hashlib . sha512 ) . digest ( ) ) <EOL> return hmac_value <EOL> class SHA256PasswordHasher ( BasePasswordHasher ) : <EOL> """<STR_LIT>""" <EOL> algorithm = '<STR_LIT>' <EOL> def encode ( self , password , salt ) : <EOL> assert password <EOL> assert salt and '<STR_LIT:$>' not in salt <EOL> hash = getattr ( hashlib , self . algorithm ) ( salt + password ) . hexdigest ( ) <EOL> return '<STR_LIT>' % ( self . algorithm , salt , hash ) <EOL> def verify ( self , password , encoded ) : <EOL> algorithm , salt , hash = encoded . split ( '<STR_LIT:$>' , <NUM_LIT:2> ) <EOL> assert algorithm == self . algorithm <EOL> encoded_2 = self . encode ( password , salt ) <EOL> return constant_time_compare ( encoded , encoded_2 ) <EOL> def safe_summary ( self , encoded ) : <EOL> algorithm , salt , hash = encoded . split ( '<STR_LIT:$>' , <NUM_LIT:2> ) <EOL> assert algorithm == self . algorithm <EOL> return SortedDict ( [ <EOL> ( '<STR_LIT>' , algorithm ) , <EOL> ( '<STR_LIT>' , mask_hash ( salt , show = <NUM_LIT:2> ) ) , <EOL> ( '<STR_LIT>' , mask_hash ( hash ) ) , <EOL> ] ) <EOL> class SHA1PasswordHasher ( SHA256PasswordHasher ) : <EOL> """<STR_LIT>""" <EOL> algorithm = '<STR_LIT>' <EOL> class SHA512PasswordHasher ( SHA256PasswordHasher ) : <EOL> """<STR_LIT>""" <EOL> algorithm = '<STR_LIT>' <EOL> class SHA512b64PasswordHasher ( SHA512PasswordHasher ) : <EOL> """<STR_LIT>""" <EOL> algorithm = '<STR_LIT>' <EOL> def encode ( self , password , salt ) : <EOL> assert password <EOL> assert salt and '<STR_LIT:$>' not in salt <EOL> hash = base64 . encodestring ( hashlib . sha512 ( salt + password ) . digest ( ) ) <EOL> return '<STR_LIT>' % ( self . algorithm , salt , hash ) </s>
