Server IP : 85.214.239.14 / Your IP : 18.219.107.243 Web Server : Apache/2.4.62 (Debian) System : Linux h2886529.stratoserver.net 4.9.0 #1 SMP Tue Jan 9 19:45:01 MSK 2024 x86_64 User : www-data ( 33) PHP Version : 7.4.18 Disable Function : pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare, MySQL : OFF | cURL : OFF | WGET : ON | Perl : ON | Python : ON | Sudo : ON | Pkexec : OFF Directory : /proc/self/root/proc/2/root/proc/3/cwd/lib/python3/dist-packages/passlib/handlers/ |
Upload File : |
"""passlib.handlers.phpass - PHPass Portable Crypt phppass located - http://www.openwall.com/phpass/ algorithm described - http://www.openwall.com/articles/PHP-Users-Passwords phpass context - blowfish, bsdi_crypt, phpass """ #============================================================================= # imports #============================================================================= # core from hashlib import md5 import logging; log = logging.getLogger(__name__) # site # pkg from passlib.utils.binary import h64 from passlib.utils.compat import u, uascii_to_str, unicode import passlib.utils.handlers as uh # local __all__ = [ "phpass", ] #============================================================================= # phpass #============================================================================= class phpass(uh.HasManyIdents, uh.HasRounds, uh.HasSalt, uh.GenericHandler): """This class implements the PHPass Portable Hash, and follows the :ref:`password-hash-api`. It supports a fixed-length salt, and a variable number of rounds. The :meth:`~passlib.ifc.PasswordHash.using` method accepts the following optional keywords: :type salt: str :param salt: Optional salt string. If not specified, one will be autogenerated (this is recommended). If specified, it must be 8 characters, drawn from the regexp range ``[./0-9A-Za-z]``. :type rounds: int :param rounds: Optional number of rounds to use. Defaults to 19, must be between 7 and 30, inclusive. This value is logarithmic, the actual number of iterations used will be :samp:`2**{rounds}`. :type ident: str :param ident: phpBB3 uses ``H`` instead of ``P`` for its identifier, this may be set to ``H`` in order to generate phpBB3 compatible hashes. it defaults to ``P``. :type relaxed: bool :param relaxed: By default, providing an invalid value for one of the other keywords will result in a :exc:`ValueError`. If ``relaxed=True``, and the error can be corrected, a :exc:`~passlib.exc.PasslibHashWarning` will be issued instead. Correctable errors include ``rounds`` that are too small or too large, and ``salt`` strings that are too long. .. versionadded:: 1.6 """ #=================================================================== # class attrs #=================================================================== #--GenericHandler-- name = "phpass" setting_kwds = ("salt", "rounds", "ident") checksum_chars = uh.HASH64_CHARS #--HasSalt-- min_salt_size = max_salt_size = 8 salt_chars = uh.HASH64_CHARS #--HasRounds-- default_rounds = 19 min_rounds = 7 max_rounds = 30 rounds_cost = "log2" #--HasManyIdents-- default_ident = u("$P$") ident_values = (u("$P$"), u("$H$")) ident_aliases = {u("P"):u("$P$"), u("H"):u("$H$")} #=================================================================== # formatting #=================================================================== #$P$9IQRaTwmfeRo7ud9Fh4E2PdI0S3r.L0 # $P$ # 9 # IQRaTwmf # eRo7ud9Fh4E2PdI0S3r.L0 @classmethod def from_string(cls, hash): ident, data = cls._parse_ident(hash) rounds, salt, chk = data[0], data[1:9], data[9:] return cls( ident=ident, rounds=h64.decode_int6(rounds.encode("ascii")), salt=salt, checksum=chk or None, ) def to_string(self): hash = u("%s%s%s%s") % (self.ident, h64.encode_int6(self.rounds).decode("ascii"), self.salt, self.checksum or u('')) return uascii_to_str(hash) #=================================================================== # backend #=================================================================== def _calc_checksum(self, secret): # FIXME: can't find definitive policy on how phpass handles non-ascii. if isinstance(secret, unicode): secret = secret.encode("utf-8") real_rounds = 1<<self.rounds result = md5(self.salt.encode("ascii") + secret).digest() r = 0 while r < real_rounds: result = md5(result + secret).digest() r += 1 return h64.encode_bytes(result).decode("ascii") #=================================================================== # eoc #=================================================================== #============================================================================= # eof #=============================================================================