Uploaded Test files
This commit is contained in:
parent
f584ad9d97
commit
2e81cb7d99
16627 changed files with 2065359 additions and 102444 deletions
49
venv/Lib/site-packages/argon2/__init__.py
Normal file
49
venv/Lib/site-packages/argon2/__init__.py
Normal file
|
@ -0,0 +1,49 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
|
||||
from . import exceptions, low_level
|
||||
from ._legacy import hash_password, hash_password_raw, verify_password
|
||||
from ._password_hasher import (
|
||||
DEFAULT_HASH_LENGTH,
|
||||
DEFAULT_MEMORY_COST,
|
||||
DEFAULT_PARALLELISM,
|
||||
DEFAULT_RANDOM_SALT_LENGTH,
|
||||
DEFAULT_TIME_COST,
|
||||
PasswordHasher,
|
||||
)
|
||||
from ._utils import Parameters, extract_parameters
|
||||
from .low_level import Type
|
||||
|
||||
|
||||
__version__ = "20.1.0"
|
||||
|
||||
__title__ = "argon2-cffi"
|
||||
__description__ = "The secure Argon2 password hashing algorithm."
|
||||
__url__ = "https://argon2-cffi.readthedocs.io/"
|
||||
__uri__ = __url__
|
||||
__doc__ = __description__ + " <" + __url__ + ">"
|
||||
|
||||
__author__ = "Hynek Schlawack"
|
||||
__email__ = "hs@ox.cx"
|
||||
|
||||
__license__ = "MIT"
|
||||
__copyright__ = "Copyright (c) 2015 " + __author__
|
||||
|
||||
|
||||
__all__ = [
|
||||
"DEFAULT_HASH_LENGTH",
|
||||
"DEFAULT_MEMORY_COST",
|
||||
"DEFAULT_PARALLELISM",
|
||||
"DEFAULT_RANDOM_SALT_LENGTH",
|
||||
"DEFAULT_TIME_COST",
|
||||
"Parameters",
|
||||
"PasswordHasher",
|
||||
"Type",
|
||||
"exceptions",
|
||||
"extract_parameters",
|
||||
"hash_password",
|
||||
"hash_password_raw",
|
||||
"low_level",
|
||||
"verify_password",
|
||||
]
|
89
venv/Lib/site-packages/argon2/__main__.py
Normal file
89
venv/Lib/site-packages/argon2/__main__.py
Normal file
|
@ -0,0 +1,89 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
|
||||
import argparse
|
||||
import sys
|
||||
import timeit
|
||||
|
||||
import six
|
||||
|
||||
from . import (
|
||||
DEFAULT_HASH_LENGTH,
|
||||
DEFAULT_MEMORY_COST,
|
||||
DEFAULT_PARALLELISM,
|
||||
DEFAULT_TIME_COST,
|
||||
PasswordHasher,
|
||||
)
|
||||
|
||||
|
||||
def main(argv):
|
||||
parser = argparse.ArgumentParser(description="Benchmark Argon2.")
|
||||
parser.add_argument(
|
||||
"-n", type=int, default=100, help="Number of iterations to measure."
|
||||
)
|
||||
parser.add_argument(
|
||||
"-t", type=int, help="`time_cost`", default=DEFAULT_TIME_COST
|
||||
)
|
||||
parser.add_argument(
|
||||
"-m", type=int, help="`memory_cost`", default=DEFAULT_MEMORY_COST
|
||||
)
|
||||
parser.add_argument(
|
||||
"-p", type=int, help="`parallellism`", default=DEFAULT_PARALLELISM
|
||||
)
|
||||
parser.add_argument(
|
||||
"-l", type=int, help="`hash_length`", default=DEFAULT_HASH_LENGTH
|
||||
)
|
||||
|
||||
args = parser.parse_args(argv[1:])
|
||||
|
||||
password = b"secret"
|
||||
ph = PasswordHasher(
|
||||
time_cost=args.t,
|
||||
memory_cost=args.m,
|
||||
parallelism=args.p,
|
||||
hash_len=args.l,
|
||||
)
|
||||
hash = ph.hash(password)
|
||||
|
||||
params = {
|
||||
"time_cost": (args.t, "iterations"),
|
||||
"memory_cost": (args.m, "KiB"),
|
||||
"parallelism": (args.p, "threads"),
|
||||
"hash_len": (args.l, "bytes"),
|
||||
}
|
||||
|
||||
print("Running Argon2id %d times with:" % (args.n,))
|
||||
|
||||
for k, v in sorted(six.iteritems(params)):
|
||||
print("%s: %d %s" % (k, v[0], v[1]))
|
||||
|
||||
print("\nMeasuring...")
|
||||
duration = timeit.timeit(
|
||||
"ph.verify({hash!r}, {password!r})".format(
|
||||
hash=hash, password=password
|
||||
),
|
||||
setup="""\
|
||||
from argon2 import PasswordHasher, Type
|
||||
|
||||
ph = PasswordHasher(
|
||||
time_cost={time_cost!r},
|
||||
memory_cost={memory_cost!r},
|
||||
parallelism={parallelism!r},
|
||||
hash_len={hash_len!r},
|
||||
)
|
||||
gc.enable()""".format(
|
||||
time_cost=args.t,
|
||||
memory_cost=args.m,
|
||||
parallelism=args.p,
|
||||
hash_len=args.l,
|
||||
),
|
||||
number=args.n,
|
||||
)
|
||||
print(
|
||||
"\n{0:.3}ms per password verification".format(duration / args.n * 1000)
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__": # pragma: nocover
|
||||
main(sys.argv)
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
venv/Lib/site-packages/argon2/__pycache__/_legacy.cpython-36.pyc
Normal file
BIN
venv/Lib/site-packages/argon2/__pycache__/_legacy.cpython-36.pyc
Normal file
Binary file not shown.
Binary file not shown.
BIN
venv/Lib/site-packages/argon2/__pycache__/_utils.cpython-36.pyc
Normal file
BIN
venv/Lib/site-packages/argon2/__pycache__/_utils.cpython-36.pyc
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
venv/Lib/site-packages/argon2/_ffi.cp36-win32.pyd
Normal file
BIN
venv/Lib/site-packages/argon2/_ffi.cp36-win32.pyd
Normal file
Binary file not shown.
191
venv/Lib/site-packages/argon2/_ffi_build.py
Normal file
191
venv/Lib/site-packages/argon2/_ffi_build.py
Normal file
|
@ -0,0 +1,191 @@
|
|||
from __future__ import absolute_import, division, print_function
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
from cffi import FFI
|
||||
|
||||
|
||||
include_dirs = [os.path.join("extras", "libargon2", "include")]
|
||||
use_system_argon2 = os.environ.get("ARGON2_CFFI_USE_SYSTEM", "0") == "1"
|
||||
if use_system_argon2:
|
||||
include_dirs = []
|
||||
|
||||
# Add vendored integer types headers.
|
||||
if "win32" in str(sys.platform).lower():
|
||||
int_base = os.path.join("extras", "msinttypes")
|
||||
inttypes = os.path.join(int_base, "inttypes")
|
||||
stdint = os.path.join(int_base, "stdint")
|
||||
vi = sys.version_info[0:2]
|
||||
if vi in [(2, 6), (2, 7)]:
|
||||
# VS 2008 needs both.
|
||||
include_dirs += [inttypes, stdint]
|
||||
elif vi in [(3, 3), (3, 4)]:
|
||||
# VS 2010 needs only inttypes.h
|
||||
include_dirs += [inttypes]
|
||||
|
||||
|
||||
ffi = FFI()
|
||||
ffi.set_source(
|
||||
"_ffi",
|
||||
"#include <argon2.h>",
|
||||
include_dirs=include_dirs,
|
||||
libraries=["argon2"],
|
||||
)
|
||||
|
||||
ffi.cdef(
|
||||
"""\
|
||||
typedef enum Argon2_type {
|
||||
Argon2_d = ...,
|
||||
Argon2_i = ...,
|
||||
Argon2_id = ...,
|
||||
} argon2_type;
|
||||
typedef enum Argon2_version {
|
||||
ARGON2_VERSION_10 = ...,
|
||||
ARGON2_VERSION_13 = ...,
|
||||
ARGON2_VERSION_NUMBER = ...
|
||||
} argon2_version;
|
||||
|
||||
int argon2_hash(const uint32_t t_cost, const uint32_t m_cost,
|
||||
const uint32_t parallelism, const void *pwd,
|
||||
const size_t pwdlen, const void *salt,
|
||||
const size_t saltlen, void *hash,
|
||||
const size_t hashlen, char *encoded,
|
||||
const size_t encodedlen, argon2_type type,
|
||||
const uint32_t version);
|
||||
|
||||
int argon2_verify(const char *encoded, const void *pwd,
|
||||
const size_t pwdlen, argon2_type type);
|
||||
|
||||
const char *argon2_error_message(int error_code);
|
||||
|
||||
|
||||
typedef int (*allocate_fptr)(uint8_t **memory, size_t bytes_to_allocate);
|
||||
typedef void (*deallocate_fptr)(uint8_t *memory, size_t bytes_to_allocate);
|
||||
|
||||
typedef struct Argon2_Context {
|
||||
uint8_t *out; /* output array */
|
||||
uint32_t outlen; /* digest length */
|
||||
|
||||
uint8_t *pwd; /* password array */
|
||||
uint32_t pwdlen; /* password length */
|
||||
|
||||
uint8_t *salt; /* salt array */
|
||||
uint32_t saltlen; /* salt length */
|
||||
|
||||
uint8_t *secret; /* key array */
|
||||
uint32_t secretlen; /* key length */
|
||||
|
||||
uint8_t *ad; /* associated data array */
|
||||
uint32_t adlen; /* associated data length */
|
||||
|
||||
uint32_t t_cost; /* number of passes */
|
||||
uint32_t m_cost; /* amount of memory requested (KB) */
|
||||
uint32_t lanes; /* number of lanes */
|
||||
uint32_t threads; /* maximum number of threads */
|
||||
|
||||
uint32_t version; /* version number */
|
||||
|
||||
allocate_fptr allocate_cbk; /* pointer to memory allocator */
|
||||
deallocate_fptr free_cbk; /* pointer to memory deallocator */
|
||||
|
||||
uint32_t flags; /* array of bool options */
|
||||
} argon2_context;
|
||||
|
||||
int argon2_ctx(argon2_context *context, argon2_type type);
|
||||
|
||||
/* Error codes */
|
||||
typedef enum Argon2_ErrorCodes {
|
||||
ARGON2_OK = ...,
|
||||
|
||||
ARGON2_OUTPUT_PTR_NULL = ...,
|
||||
|
||||
ARGON2_OUTPUT_TOO_SHORT = ...,
|
||||
ARGON2_OUTPUT_TOO_LONG = ...,
|
||||
|
||||
ARGON2_PWD_TOO_SHORT = ...,
|
||||
ARGON2_PWD_TOO_LONG = ...,
|
||||
|
||||
ARGON2_SALT_TOO_SHORT = ...,
|
||||
ARGON2_SALT_TOO_LONG = ...,
|
||||
|
||||
ARGON2_AD_TOO_SHORT = ...,
|
||||
ARGON2_AD_TOO_LONG = ...,
|
||||
|
||||
ARGON2_SECRET_TOO_SHORT = ...,
|
||||
ARGON2_SECRET_TOO_LONG = ...,
|
||||
|
||||
ARGON2_TIME_TOO_SMALL = ...,
|
||||
ARGON2_TIME_TOO_LARGE = ...,
|
||||
|
||||
ARGON2_MEMORY_TOO_LITTLE = ...,
|
||||
ARGON2_MEMORY_TOO_MUCH = ...,
|
||||
|
||||
ARGON2_LANES_TOO_FEW = ...,
|
||||
ARGON2_LANES_TOO_MANY = ...,
|
||||
|
||||
ARGON2_PWD_PTR_MISMATCH = ..., /* NULL ptr with non-zero length */
|
||||
ARGON2_SALT_PTR_MISMATCH = ..., /* NULL ptr with non-zero length */
|
||||
ARGON2_SECRET_PTR_MISMATCH = ..., /* NULL ptr with non-zero length */
|
||||
ARGON2_AD_PTR_MISMATCH = ..., /* NULL ptr with non-zero length */
|
||||
|
||||
ARGON2_MEMORY_ALLOCATION_ERROR = ...,
|
||||
|
||||
ARGON2_FREE_MEMORY_CBK_NULL = ...,
|
||||
ARGON2_ALLOCATE_MEMORY_CBK_NULL = ...,
|
||||
|
||||
ARGON2_INCORRECT_PARAMETER = ...,
|
||||
ARGON2_INCORRECT_TYPE = ...,
|
||||
|
||||
ARGON2_OUT_PTR_MISMATCH = ...,
|
||||
|
||||
ARGON2_THREADS_TOO_FEW = ...,
|
||||
ARGON2_THREADS_TOO_MANY = ...,
|
||||
|
||||
ARGON2_MISSING_ARGS = ...,
|
||||
|
||||
ARGON2_ENCODING_FAIL = ...,
|
||||
|
||||
ARGON2_DECODING_FAIL = ...,
|
||||
|
||||
ARGON2_THREAD_FAIL = ...,
|
||||
|
||||
ARGON2_DECODING_LENGTH_FAIL= ...,
|
||||
|
||||
ARGON2_VERIFY_MISMATCH = ...,
|
||||
} argon2_error_codes;
|
||||
|
||||
#define ARGON2_FLAG_CLEAR_PASSWORD ...
|
||||
#define ARGON2_FLAG_CLEAR_SECRET ...
|
||||
#define ARGON2_DEFAULT_FLAGS ...
|
||||
|
||||
#define ARGON2_MIN_LANES ...
|
||||
#define ARGON2_MAX_LANES ...
|
||||
#define ARGON2_MIN_THREADS ...
|
||||
#define ARGON2_MAX_THREADS ...
|
||||
#define ARGON2_SYNC_POINTS ...
|
||||
#define ARGON2_MIN_OUTLEN ...
|
||||
#define ARGON2_MAX_OUTLEN ...
|
||||
#define ARGON2_MIN_MEMORY ...
|
||||
#define ARGON2_MAX_MEMORY_BITS ...
|
||||
#define ARGON2_MAX_MEMORY ...
|
||||
#define ARGON2_MIN_TIME ...
|
||||
#define ARGON2_MAX_TIME ...
|
||||
#define ARGON2_MIN_PWD_LENGTH ...
|
||||
#define ARGON2_MAX_PWD_LENGTH ...
|
||||
#define ARGON2_MIN_AD_LENGTH ...
|
||||
#define ARGON2_MAX_AD_LENGTH ...
|
||||
#define ARGON2_MIN_SALT_LENGTH ...
|
||||
#define ARGON2_MAX_SALT_LENGTH ...
|
||||
#define ARGON2_MIN_SECRET ...
|
||||
#define ARGON2_MAX_SECRET ...
|
||||
|
||||
uint32_t argon2_encodedlen(uint32_t t_cost, uint32_t m_cost,
|
||||
uint32_t parallelism, uint32_t saltlen,
|
||||
uint32_t hashlen, argon2_type type);
|
||||
|
||||
"""
|
||||
)
|
||||
|
||||
if __name__ == "__main__":
|
||||
ffi.compile()
|
70
venv/Lib/site-packages/argon2/_legacy.py
Normal file
70
venv/Lib/site-packages/argon2/_legacy.py
Normal file
|
@ -0,0 +1,70 @@
|
|||
"""
|
||||
Legacy mid-level functions.
|
||||
"""
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
|
||||
import os
|
||||
|
||||
from ._password_hasher import (
|
||||
DEFAULT_HASH_LENGTH,
|
||||
DEFAULT_MEMORY_COST,
|
||||
DEFAULT_PARALLELISM,
|
||||
DEFAULT_RANDOM_SALT_LENGTH,
|
||||
DEFAULT_TIME_COST,
|
||||
)
|
||||
from .low_level import Type, hash_secret, hash_secret_raw, verify_secret
|
||||
|
||||
|
||||
def hash_password(
|
||||
password,
|
||||
salt=None,
|
||||
time_cost=DEFAULT_TIME_COST,
|
||||
memory_cost=DEFAULT_MEMORY_COST,
|
||||
parallelism=DEFAULT_PARALLELISM,
|
||||
hash_len=DEFAULT_HASH_LENGTH,
|
||||
type=Type.I,
|
||||
):
|
||||
"""
|
||||
Legacy alias for :func:`hash_secret` with default parameters.
|
||||
|
||||
.. deprecated:: 16.0.0
|
||||
Use :class:`argon2.PasswordHasher` for passwords.
|
||||
"""
|
||||
if salt is None:
|
||||
salt = os.urandom(DEFAULT_RANDOM_SALT_LENGTH)
|
||||
return hash_secret(
|
||||
password, salt, time_cost, memory_cost, parallelism, hash_len, type
|
||||
)
|
||||
|
||||
|
||||
def hash_password_raw(
|
||||
password,
|
||||
salt=None,
|
||||
time_cost=DEFAULT_TIME_COST,
|
||||
memory_cost=DEFAULT_MEMORY_COST,
|
||||
parallelism=DEFAULT_PARALLELISM,
|
||||
hash_len=DEFAULT_HASH_LENGTH,
|
||||
type=Type.I,
|
||||
):
|
||||
"""
|
||||
Legacy alias for :func:`hash_secret_raw` with default parameters.
|
||||
|
||||
.. deprecated:: 16.0.0
|
||||
Use :class:`argon2.PasswordHasher` for passwords.
|
||||
"""
|
||||
if salt is None:
|
||||
salt = os.urandom(DEFAULT_RANDOM_SALT_LENGTH)
|
||||
return hash_secret_raw(
|
||||
password, salt, time_cost, memory_cost, parallelism, hash_len, type
|
||||
)
|
||||
|
||||
|
||||
def verify_password(hash, password, type=Type.I):
|
||||
"""
|
||||
Legacy alias for :func:`verify_secret` with default parameters.
|
||||
|
||||
.. deprecated:: 16.0.0
|
||||
Use :class:`argon2.PasswordHasher` for passwords.
|
||||
"""
|
||||
return verify_secret(hash, password, type)
|
212
venv/Lib/site-packages/argon2/_password_hasher.py
Normal file
212
venv/Lib/site-packages/argon2/_password_hasher.py
Normal file
|
@ -0,0 +1,212 @@
|
|||
from __future__ import absolute_import, division, print_function
|
||||
|
||||
import os
|
||||
|
||||
from ._utils import Parameters, _check_types, extract_parameters
|
||||
from .exceptions import InvalidHash
|
||||
from .low_level import Type, hash_secret, verify_secret
|
||||
|
||||
|
||||
DEFAULT_RANDOM_SALT_LENGTH = 16
|
||||
DEFAULT_HASH_LENGTH = 16
|
||||
DEFAULT_TIME_COST = 2
|
||||
DEFAULT_MEMORY_COST = 102400
|
||||
DEFAULT_PARALLELISM = 8
|
||||
|
||||
|
||||
def _ensure_bytes(s, encoding):
|
||||
"""
|
||||
Ensure *s* is a bytes string. Encode using *encoding* if it isn't.
|
||||
"""
|
||||
if isinstance(s, bytes):
|
||||
return s
|
||||
return s.encode(encoding)
|
||||
|
||||
|
||||
class PasswordHasher(object):
|
||||
r"""
|
||||
High level class to hash passwords with sensible defaults.
|
||||
|
||||
Uses Argon2\ **id** by default and always uses a random salt_ for hashing.
|
||||
But it can verify any type of Argon2 as long as the hash is correctly
|
||||
encoded.
|
||||
|
||||
The reason for this being a class is both for convenience to carry
|
||||
parameters and to verify the parameters only *once*. Any unnecessary
|
||||
slowdown when hashing is a tangible advantage for a brute force attacker.
|
||||
|
||||
:param int time_cost: Defines the amount of computation realized and
|
||||
therefore the execution time, given in number of iterations.
|
||||
:param int memory_cost: Defines the memory usage, given in kibibytes_.
|
||||
:param int parallelism: Defines the number of parallel threads (*changes*
|
||||
the resulting hash value).
|
||||
:param int hash_len: Length of the hash in bytes.
|
||||
:param int salt_len: Length of random salt to be generated for each
|
||||
password.
|
||||
:param str encoding: The Argon2 C library expects bytes. So if
|
||||
:meth:`hash` or :meth:`verify` are passed an unicode string, it will be
|
||||
encoded using this encoding.
|
||||
:param Type type: Argon2 type to use. Only change for interoperability
|
||||
with legacy systems.
|
||||
|
||||
.. versionadded:: 16.0.0
|
||||
.. versionchanged:: 18.2.0
|
||||
Switch from Argon2i to Argon2id based on the recommendation by the
|
||||
current RFC_ draft.
|
||||
.. versionchanged:: 18.2.0
|
||||
Changed default *memory_cost* to 100 MiB and default *parallelism* to 8.
|
||||
.. versionchanged:: 18.2.0 ``verify`` now will determine the type of hash.
|
||||
.. versionchanged:: 18.3.0 The Argon2 type is configurable now.
|
||||
|
||||
.. _salt: https://en.wikipedia.org/wiki/Salt_(cryptography)
|
||||
.. _kibibytes: https://en.wikipedia.org/wiki/Binary_prefix#kibi
|
||||
.. _RFC: https://tools.ietf.org/html/draft-irtf-cfrg-argon2-04#section-4
|
||||
"""
|
||||
__slots__ = ["_parameters", "encoding"]
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
time_cost=DEFAULT_TIME_COST,
|
||||
memory_cost=DEFAULT_MEMORY_COST,
|
||||
parallelism=DEFAULT_PARALLELISM,
|
||||
hash_len=DEFAULT_HASH_LENGTH,
|
||||
salt_len=DEFAULT_RANDOM_SALT_LENGTH,
|
||||
encoding="utf-8",
|
||||
type=Type.ID,
|
||||
):
|
||||
e = _check_types(
|
||||
time_cost=(time_cost, int),
|
||||
memory_cost=(memory_cost, int),
|
||||
parallelism=(parallelism, int),
|
||||
hash_len=(hash_len, int),
|
||||
salt_len=(salt_len, int),
|
||||
encoding=(encoding, str),
|
||||
type=(type, Type),
|
||||
)
|
||||
if e:
|
||||
raise TypeError(e)
|
||||
|
||||
# Cache a Parameters object for check_needs_rehash.
|
||||
self._parameters = Parameters(
|
||||
type=type,
|
||||
version=19,
|
||||
salt_len=salt_len,
|
||||
hash_len=hash_len,
|
||||
time_cost=time_cost,
|
||||
memory_cost=memory_cost,
|
||||
parallelism=parallelism,
|
||||
)
|
||||
self.encoding = encoding
|
||||
|
||||
@property
|
||||
def time_cost(self):
|
||||
return self._parameters.time_cost
|
||||
|
||||
@property
|
||||
def memory_cost(self):
|
||||
return self._parameters.memory_cost
|
||||
|
||||
@property
|
||||
def parallelism(self):
|
||||
return self._parameters.parallelism
|
||||
|
||||
@property
|
||||
def hash_len(self):
|
||||
return self._parameters.hash_len
|
||||
|
||||
@property
|
||||
def salt_len(self):
|
||||
return self._parameters.salt_len
|
||||
|
||||
@property
|
||||
def type(self):
|
||||
return self._parameters.type
|
||||
|
||||
def hash(self, password):
|
||||
"""
|
||||
Hash *password* and return an encoded hash.
|
||||
|
||||
:param password: Password to hash.
|
||||
:type password: ``bytes`` or ``unicode``
|
||||
|
||||
:raises argon2.exceptions.HashingError: If hashing fails.
|
||||
|
||||
:rtype: unicode
|
||||
"""
|
||||
return hash_secret(
|
||||
secret=_ensure_bytes(password, self.encoding),
|
||||
salt=os.urandom(self.salt_len),
|
||||
time_cost=self.time_cost,
|
||||
memory_cost=self.memory_cost,
|
||||
parallelism=self.parallelism,
|
||||
hash_len=self.hash_len,
|
||||
type=self.type,
|
||||
).decode("ascii")
|
||||
|
||||
_header_to_type = {
|
||||
b"$argon2i$": Type.I,
|
||||
b"$argon2d$": Type.D,
|
||||
b"$argon2id": Type.ID,
|
||||
}
|
||||
|
||||
def verify(self, hash, password):
|
||||
"""
|
||||
Verify that *password* matches *hash*.
|
||||
|
||||
.. warning::
|
||||
|
||||
It is assumed that the caller is in full control of the hash. No
|
||||
other parsing than the determination of the hash type is done by
|
||||
``argon2-cffi``.
|
||||
|
||||
:param hash: An encoded hash as returned from
|
||||
:meth:`PasswordHasher.hash`.
|
||||
:type hash: ``bytes`` or ``unicode``
|
||||
|
||||
:param password: The password to verify.
|
||||
:type password: ``bytes`` or ``unicode``
|
||||
|
||||
:raises argon2.exceptions.VerifyMismatchError: If verification fails
|
||||
because *hash* is not valid for *password*.
|
||||
:raises argon2.exceptions.VerificationError: If verification fails for
|
||||
other reasons.
|
||||
:raises argon2.exceptions.InvalidHash: If *hash* is so clearly
|
||||
invalid, that it couldn't be passed to Argon2.
|
||||
|
||||
:return: ``True`` on success, raise
|
||||
:exc:`~argon2.exceptions.VerificationError` otherwise.
|
||||
:rtype: bool
|
||||
|
||||
.. versionchanged:: 16.1.0
|
||||
Raise :exc:`~argon2.exceptions.VerifyMismatchError` on mismatches
|
||||
instead of its more generic superclass.
|
||||
.. versionadded:: 18.2.0 Hash type agility.
|
||||
"""
|
||||
hash = _ensure_bytes(hash, "ascii")
|
||||
try:
|
||||
hash_type = self._header_to_type[hash[:9]]
|
||||
except (IndexError, KeyError, LookupError):
|
||||
raise InvalidHash()
|
||||
|
||||
return verify_secret(
|
||||
hash, _ensure_bytes(password, self.encoding), hash_type
|
||||
)
|
||||
|
||||
def check_needs_rehash(self, hash):
|
||||
"""
|
||||
Check whether *hash* was created using the instance's parameters.
|
||||
|
||||
Whenever your Argon2 parameters -- or ``argon2-cffi``'s defaults! --
|
||||
change, you should rehash your passwords at the next opportunity. The
|
||||
common approach is to do that whenever a user logs in, since that
|
||||
should be the only time when you have access to the cleartext
|
||||
password.
|
||||
|
||||
Therefore it's best practice to check -- and if necessary rehash --
|
||||
passwords after each successful authentication.
|
||||
|
||||
:rtype: bool
|
||||
|
||||
.. versionadded:: 18.2.0
|
||||
"""
|
||||
return self._parameters != extract_parameters(hash)
|
198
venv/Lib/site-packages/argon2/_utils.py
Normal file
198
venv/Lib/site-packages/argon2/_utils.py
Normal file
|
@ -0,0 +1,198 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
|
||||
from six import iteritems
|
||||
|
||||
from .exceptions import InvalidHash
|
||||
from .low_level import Type
|
||||
|
||||
|
||||
NoneType = type(None)
|
||||
|
||||
|
||||
def _check_types(**kw):
|
||||
"""
|
||||
Check each ``name: (value, types)`` in *kw*.
|
||||
|
||||
Returns a human-readable string of all violations or `None``.
|
||||
"""
|
||||
errors = []
|
||||
for name, (value, types) in iteritems(kw):
|
||||
if not isinstance(value, types):
|
||||
if isinstance(types, tuple):
|
||||
types = ", or ".join(t.__name__ for t in types)
|
||||
else:
|
||||
types = types.__name__
|
||||
errors.append(
|
||||
"'{name}' must be a {type} (got {actual})".format(
|
||||
name=name, type=types, actual=type(value).__name__
|
||||
)
|
||||
)
|
||||
|
||||
if errors != []:
|
||||
return ", ".join(errors) + "."
|
||||
|
||||
|
||||
def _encoded_str_len(l):
|
||||
"""
|
||||
Compute how long a byte string of length *l* becomes if encoded to hex.
|
||||
"""
|
||||
return (l << 2) / 3 + 2
|
||||
|
||||
|
||||
def _decoded_str_len(l):
|
||||
"""
|
||||
Compute how long an encoded string of length *l* becomes.
|
||||
"""
|
||||
rem = l % 4
|
||||
|
||||
if rem == 3:
|
||||
last_group_len = 2
|
||||
elif rem == 2:
|
||||
last_group_len = 1
|
||||
else:
|
||||
last_group_len = 0
|
||||
|
||||
return l // 4 * 3 + last_group_len
|
||||
|
||||
|
||||
class Parameters(object):
|
||||
"""
|
||||
Argon2 hash parameters.
|
||||
|
||||
See :doc:`parameters` on how to pick them.
|
||||
|
||||
:ivar Type type: Hash type.
|
||||
:ivar int version: Argon2 version.
|
||||
:ivar int salt_len: Length of the salt in bytes.
|
||||
:ivar int hash_len: Length of the hash in bytes.
|
||||
:ivar int time_cost: Time cost in iterations.
|
||||
:ivar int memory_cost: Memory cost in kibibytes.
|
||||
:ivar int parallelism: Number of parallel threads.
|
||||
|
||||
.. versionadded:: 18.2.0
|
||||
"""
|
||||
|
||||
__slots__ = [
|
||||
"type",
|
||||
"version",
|
||||
"salt_len",
|
||||
"hash_len",
|
||||
"time_cost",
|
||||
"memory_cost",
|
||||
"parallelism",
|
||||
]
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
type,
|
||||
version,
|
||||
salt_len,
|
||||
hash_len,
|
||||
time_cost,
|
||||
memory_cost,
|
||||
parallelism,
|
||||
):
|
||||
self.type = type
|
||||
self.version = version
|
||||
self.salt_len = salt_len
|
||||
self.hash_len = hash_len
|
||||
self.time_cost = time_cost
|
||||
self.memory_cost = memory_cost
|
||||
self.parallelism = parallelism
|
||||
|
||||
def __repr__(self):
|
||||
return (
|
||||
"<Parameters(type=%r, version=%d, hash_len=%d, salt_len=%d, "
|
||||
"time_cost=%d, memory_cost=%d, parallelelism=%d)>"
|
||||
% (
|
||||
self.type,
|
||||
self.version,
|
||||
self.hash_len,
|
||||
self.salt_len,
|
||||
self.time_cost,
|
||||
self.memory_cost,
|
||||
self.parallelism,
|
||||
)
|
||||
)
|
||||
|
||||
def __eq__(self, other):
|
||||
if self.__class__ != other.__class__:
|
||||
return NotImplemented
|
||||
|
||||
return (
|
||||
self.type,
|
||||
self.version,
|
||||
self.salt_len,
|
||||
self.hash_len,
|
||||
self.time_cost,
|
||||
self.memory_cost,
|
||||
self.parallelism,
|
||||
) == (
|
||||
other.type,
|
||||
other.version,
|
||||
other.salt_len,
|
||||
other.hash_len,
|
||||
other.time_cost,
|
||||
other.memory_cost,
|
||||
other.parallelism,
|
||||
)
|
||||
|
||||
def __ne__(self, other):
|
||||
if self.__class__ != other.__class__:
|
||||
return NotImplemented
|
||||
|
||||
return not self.__eq__(other)
|
||||
|
||||
|
||||
_NAME_TO_TYPE = {"argon2id": Type.ID, "argon2i": Type.I, "argon2d": Type.D}
|
||||
_REQUIRED_KEYS = sorted(("v", "m", "t", "p"))
|
||||
|
||||
|
||||
def extract_parameters(hash):
|
||||
"""
|
||||
Extract parameters from an encoded *hash*.
|
||||
|
||||
:param str params: An encoded Argon2 hash string.
|
||||
|
||||
:rtype: Parameters
|
||||
|
||||
.. versionadded:: 18.2.0
|
||||
"""
|
||||
parts = hash.split("$")
|
||||
|
||||
# Backwards compatibility for Argon v1.2 hashes
|
||||
if len(parts) == 5:
|
||||
parts.insert(2, "v=18")
|
||||
|
||||
if len(parts) != 6:
|
||||
raise InvalidHash
|
||||
|
||||
if parts[0] != "":
|
||||
raise InvalidHash
|
||||
|
||||
try:
|
||||
type = _NAME_TO_TYPE[parts[1]]
|
||||
|
||||
kvs = {
|
||||
k: int(v)
|
||||
for k, v in (
|
||||
s.split("=") for s in [parts[2]] + parts[3].split(",")
|
||||
)
|
||||
}
|
||||
except Exception:
|
||||
raise InvalidHash
|
||||
|
||||
if sorted(kvs.keys()) != _REQUIRED_KEYS:
|
||||
raise InvalidHash
|
||||
|
||||
return Parameters(
|
||||
type=type,
|
||||
salt_len=_decoded_str_len(len(parts[4])),
|
||||
hash_len=_decoded_str_len(len(parts[5])),
|
||||
version=kvs["v"],
|
||||
time_cost=kvs["t"],
|
||||
memory_cost=kvs["m"],
|
||||
parallelism=kvs["p"],
|
||||
)
|
45
venv/Lib/site-packages/argon2/exceptions.py
Normal file
45
venv/Lib/site-packages/argon2/exceptions.py
Normal file
|
@ -0,0 +1,45 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
|
||||
|
||||
class Argon2Error(Exception):
|
||||
"""
|
||||
Superclass of all argon2 exceptions.
|
||||
|
||||
Never thrown directly.
|
||||
"""
|
||||
|
||||
|
||||
class VerificationError(Argon2Error):
|
||||
"""
|
||||
Verification failed.
|
||||
|
||||
You can find the original error message from Argon2 in ``args[0]``.
|
||||
"""
|
||||
|
||||
|
||||
class VerifyMismatchError(VerificationError):
|
||||
"""
|
||||
The secret does not match the hash.
|
||||
|
||||
Subclass of :exc:`argon2.exceptions.VerificationError`.
|
||||
|
||||
.. versionadded:: 16.1.0
|
||||
"""
|
||||
|
||||
|
||||
class HashingError(Argon2Error):
|
||||
"""
|
||||
Raised if hashing failed.
|
||||
|
||||
You can find the original error message from Argon2 in ``args[0]``.
|
||||
"""
|
||||
|
||||
|
||||
class InvalidHash(ValueError):
|
||||
"""
|
||||
Raised if the hash is invalid before passing it to Argon2.
|
||||
|
||||
.. versionadded:: 18.2.0
|
||||
"""
|
256
venv/Lib/site-packages/argon2/low_level.py
Normal file
256
venv/Lib/site-packages/argon2/low_level.py
Normal file
|
@ -0,0 +1,256 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Low-level functions if you want to build your own higher level abstractions.
|
||||
|
||||
.. warning::
|
||||
This is a "Hazardous Materials" module. You should **ONLY** use it if
|
||||
you're 100% absolutely sure that you know what you’re doing because this
|
||||
module is full of land mines, dragons, and dinosaurs with laser guns.
|
||||
"""
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
|
||||
from enum import Enum
|
||||
|
||||
from six import PY3
|
||||
|
||||
from ._ffi import ffi, lib
|
||||
from .exceptions import HashingError, VerificationError, VerifyMismatchError
|
||||
|
||||
|
||||
__all__ = [
|
||||
"ARGON2_VERSION",
|
||||
"Type",
|
||||
"ffi",
|
||||
"hash_secret",
|
||||
"hash_secret_raw",
|
||||
"verify_secret",
|
||||
]
|
||||
|
||||
ARGON2_VERSION = lib.ARGON2_VERSION_NUMBER
|
||||
"""
|
||||
The latest version of the Argon2 algorithm that is supported (and used by
|
||||
default).
|
||||
|
||||
.. versionadded:: 16.1.0
|
||||
"""
|
||||
|
||||
|
||||
class Type(Enum):
|
||||
"""
|
||||
Enum of Argon2 variants.
|
||||
|
||||
Please see :doc:`parameters` on how to pick one.
|
||||
"""
|
||||
|
||||
D = lib.Argon2_d
|
||||
r"""
|
||||
Argon2\ **d** is faster and uses data-depending memory access, which makes
|
||||
it less suitable for hashing secrets and more suitable for cryptocurrencies
|
||||
and applications with no threats from side-channel timing attacks.
|
||||
"""
|
||||
I = lib.Argon2_i
|
||||
r"""
|
||||
Argon2\ **i** uses data-independent memory access. Argon2i is slower as
|
||||
it makes more passes over the memory to protect from tradeoff attacks.
|
||||
"""
|
||||
ID = lib.Argon2_id
|
||||
r"""
|
||||
Argon2\ **id** is a hybrid of Argon2i and Argon2d, using a combination of
|
||||
data-depending and data-independent memory accesses, which gives some of
|
||||
Argon2i's resistance to side-channel cache timing attacks and much of
|
||||
Argon2d's resistance to GPU cracking attacks.
|
||||
|
||||
That makes it the preferred type for password hashing and password-based
|
||||
key derivation.
|
||||
|
||||
.. versionadded:: 16.3.0
|
||||
"""
|
||||
|
||||
|
||||
def hash_secret(
|
||||
secret,
|
||||
salt,
|
||||
time_cost,
|
||||
memory_cost,
|
||||
parallelism,
|
||||
hash_len,
|
||||
type,
|
||||
version=ARGON2_VERSION,
|
||||
):
|
||||
"""
|
||||
Hash *secret* and return an **encoded** hash.
|
||||
|
||||
An encoded hash can be directly passed into :func:`verify_secret` as it
|
||||
contains all parameters and the salt.
|
||||
|
||||
:param bytes secret: Secret to hash.
|
||||
:param bytes salt: A salt_. Should be random and different for each
|
||||
secret.
|
||||
:param Type type: Which Argon2 variant to use.
|
||||
:param int version: Which Argon2 version to use.
|
||||
|
||||
For an explanation of the Argon2 parameters see :class:`PasswordHasher`.
|
||||
|
||||
:rtype: bytes
|
||||
|
||||
:raises argon2.exceptions.HashingError: If hashing fails.
|
||||
|
||||
.. versionadded:: 16.0.0
|
||||
|
||||
.. _salt: https://en.wikipedia.org/wiki/Salt_(cryptography)
|
||||
.. _kibibytes: https://en.wikipedia.org/wiki/Binary_prefix#kibi
|
||||
"""
|
||||
size = (
|
||||
lib.argon2_encodedlen(
|
||||
time_cost,
|
||||
memory_cost,
|
||||
parallelism,
|
||||
len(salt),
|
||||
hash_len,
|
||||
type.value,
|
||||
)
|
||||
+ 1
|
||||
)
|
||||
buf = ffi.new("char[]", size)
|
||||
rv = lib.argon2_hash(
|
||||
time_cost,
|
||||
memory_cost,
|
||||
parallelism,
|
||||
ffi.new("uint8_t[]", secret),
|
||||
len(secret),
|
||||
ffi.new("uint8_t[]", salt),
|
||||
len(salt),
|
||||
ffi.NULL,
|
||||
hash_len,
|
||||
buf,
|
||||
size,
|
||||
type.value,
|
||||
version,
|
||||
)
|
||||
if rv != lib.ARGON2_OK:
|
||||
raise HashingError(error_to_str(rv))
|
||||
|
||||
return ffi.string(buf)
|
||||
|
||||
|
||||
def hash_secret_raw(
|
||||
secret,
|
||||
salt,
|
||||
time_cost,
|
||||
memory_cost,
|
||||
parallelism,
|
||||
hash_len,
|
||||
type,
|
||||
version=ARGON2_VERSION,
|
||||
):
|
||||
"""
|
||||
Hash *password* and return a **raw** hash.
|
||||
|
||||
This function takes the same parameters as :func:`hash_secret`.
|
||||
|
||||
.. versionadded:: 16.0.0
|
||||
"""
|
||||
buf = ffi.new("uint8_t[]", hash_len)
|
||||
|
||||
rv = lib.argon2_hash(
|
||||
time_cost,
|
||||
memory_cost,
|
||||
parallelism,
|
||||
ffi.new("uint8_t[]", secret),
|
||||
len(secret),
|
||||
ffi.new("uint8_t[]", salt),
|
||||
len(salt),
|
||||
buf,
|
||||
hash_len,
|
||||
ffi.NULL,
|
||||
0,
|
||||
type.value,
|
||||
version,
|
||||
)
|
||||
if rv != lib.ARGON2_OK:
|
||||
raise HashingError(error_to_str(rv))
|
||||
|
||||
return bytes(ffi.buffer(buf, hash_len))
|
||||
|
||||
|
||||
def verify_secret(hash, secret, type):
|
||||
"""
|
||||
Verify whether *secret* is correct for *hash* of *type*.
|
||||
|
||||
:param bytes hash: An encoded Argon2 hash as returned by
|
||||
:func:`hash_secret`.
|
||||
:param bytes secret: The secret to verify whether it matches the one
|
||||
in *hash*.
|
||||
:param Type type: Type for *hash*.
|
||||
|
||||
:raises argon2.exceptions.VerifyMismatchError: If verification fails
|
||||
because *hash* is not valid for *secret* of *type*.
|
||||
:raises argon2.exceptions.VerificationError: If verification fails for
|
||||
other reasons.
|
||||
|
||||
:return: ``True`` on success, raise
|
||||
:exc:`~argon2.exceptions.VerificationError` otherwise.
|
||||
:rtype: bool
|
||||
|
||||
.. versionadded:: 16.0.0
|
||||
.. versionchanged:: 16.1.0
|
||||
Raise :exc:`~argon2.exceptions.VerifyMismatchError` on mismatches
|
||||
instead of its more generic superclass.
|
||||
"""
|
||||
rv = lib.argon2_verify(
|
||||
ffi.new("char[]", hash),
|
||||
ffi.new("uint8_t[]", secret),
|
||||
len(secret),
|
||||
type.value,
|
||||
)
|
||||
if rv == lib.ARGON2_OK:
|
||||
return True
|
||||
elif rv == lib.ARGON2_VERIFY_MISMATCH:
|
||||
raise VerifyMismatchError(error_to_str(rv))
|
||||
else:
|
||||
raise VerificationError(error_to_str(rv))
|
||||
|
||||
|
||||
def core(context, type):
|
||||
"""
|
||||
Direct binding to the ``argon2_ctx`` function.
|
||||
|
||||
.. warning::
|
||||
This is a strictly advanced function working on raw C data structures.
|
||||
Both Argon2's and ``argon2-cffi``'s higher-level bindings do a lot of
|
||||
sanity checks and housekeeping work that *you* are now responsible for
|
||||
(e.g. clearing buffers). The structure of the *context* object can,
|
||||
has, and will change with *any* release!
|
||||
|
||||
Use at your own peril; ``argon2-cffi`` does *not* use this binding
|
||||
itself.
|
||||
|
||||
:param context: A CFFI Argon2 context object (i.e. an ``struct
|
||||
Argon2_Context``/``argon2_context``).
|
||||
:param int type: Which Argon2 variant to use. You can use the ``value``
|
||||
field of :class:`Type`'s fields.
|
||||
|
||||
:rtype: int
|
||||
:return: An Argon2 error code. Can be transformed into a string using
|
||||
:func:`error_to_str`.
|
||||
|
||||
.. versionadded:: 16.0.0
|
||||
"""
|
||||
return lib.argon2_ctx(context, type)
|
||||
|
||||
|
||||
def error_to_str(error):
|
||||
"""
|
||||
Convert an Argon2 error code into a native string.
|
||||
|
||||
:param int error: An Argon2 error code as returned by :func:`core`.
|
||||
|
||||
:rtype: str
|
||||
|
||||
.. versionadded:: 16.0.0
|
||||
"""
|
||||
msg = ffi.string(lib.argon2_error_message(error))
|
||||
if PY3:
|
||||
msg = msg.decode("ascii")
|
||||
return msg
|
Loading…
Add table
Add a link
Reference in a new issue