Beispiel #1
0
 def _crypt(self, password: str):
     if self._kdf_memlimit > MEMLIMIT_MAX:
         raise Error('memlimit too high')
     opslimit = max(32768, self._kdf_opslimit)
     n_log2 = 1
     r = 8
     p = 0
     if opslimit < self._kdf_memlimit // 32:
         maxn = opslimit // (r * 4)
         p = 1
     else:
         maxn = self._kdf_memlimit // (r * 128)
     while n_log2 < 63:
         if 1 << n_log2 > maxn // 2:
             break
         n_log2 += 1
     if not p:
         p = min(0x3fffffff, (opslimit // 4) // (1 << n_log2)) // r
     if n_log2 > N_LOG2_MAX:
         raise Error('n_log2 too high')
     self._keynum_sk.xor(
         scrypt.Scrypt(
             salt=self._kdf_salt,
             length=KEYNUM_SK_LEN,
             n=1 << n_log2,
             r=r,
             p=p,
         ).derive(password.encode()))
Beispiel #2
0
    def verify_password(password: bytes, password_hash: str) -> bool:
        """ verify a given password matches the given password hash

        raises TypeError, ValueError if the input is not well formed

        returns True if the password matches the hash. otherwise False

        The output of hash_password contains the parameters and salt as well
        as the hashed password. This allows for hash_password to be upgraded
        in the future with better algorithms, while allowing verify_password
        to be able to verify passwords hashed using old versions.

        :param password: the user supplied password encoded as bytes
        :param password_hash: a hash previously determined using hash_password()
        """

        if not isinstance(password, bytes):
            raise TypeError("expected bytes received %s" % type(password))

        if not isinstance(password_hash, str):
            raise TypeError("expected bytes received %s" % type(password))

        digest = hashes.Hash(hashes.SHA256(), backend=default_backend())
        digest.update(password)
        key_material = digest.finalize()

        parts = password_hash.encode('utf-8').split(b':')
        kind = parts[0]
        version = parts[1]
        params = base64.b64decode(parts[2])
        data = base64.b64decode(parts[3])

        if kind != b'scrypt' or version != b"1":
            raise ValueError("invalid method")

        if version != b"1":
            raise ValueError("invalid version")

        e = None
        try:
            N, r, p, salt_length, length = struct.unpack(">HBBBB", params)
        except struct.error as ex:
            e = ValueError(str(ex))
        if e:
            raise e

        salt = data[:salt_length]
        expected = data[salt_length:]

        kdf = scrypt.Scrypt(salt, length, N, r, p, backend=default_backend())

        result = False
        try:
            kdf.verify(key_material, expected)
            result = True
        except InvalidKey as e:
            pass

        return result
Beispiel #3
0
    def hash_password(password: bytes) -> str:
        """ hash a password

        :return: the hashed password

        The output string contains the parameters used to define the hash, as well
        as the randomly generated salt used.

        Implementation notes: This method pre-hashes the password using sha-256.
        A salt is generated and then it then hashes the output using
        scrypt with parameters N=16384, r=16, p=1.

        :param password: the user supplied password encoded as bytes

        """

        if not isinstance(password, bytes):
            raise TypeError("expected bytes received %s" % type(password))

        digest = hashes.Hash(hashes.SHA256(), backend=default_backend())
        digest.update(password)
        key_material = digest.finalize()

        # N: iteration count
        # r: block size
        # p: parallelism factor
        # Memory required = 128 * N * r * p bytes
        # Memory required = 128 * 16384 * 16 * 1 bytes
        # Memory required = 33554432 bytes
        # Memory required = 32768 KB
        # Memory required = 32.0 MB
        N = 16384
        r = 16
        p = 1
        salt = os.urandom(Auth.SALT_LENGTH)

        params = struct.pack(">HBBBB", N, r, p, Auth.SALT_LENGTH,
                             Auth.DIGEST_LENGTH)

        # format:
        #  method:version:params:salt+hash

        header = b"scrypt:1:" + base64.b64encode(params) + b":"

        kdf = scrypt.Scrypt(salt,
                            Auth.DIGEST_LENGTH,
                            N,
                            r,
                            p,
                            backend=default_backend())
        out = kdf.derive(key_material)

        footer = base64.b64encode(salt + out)

        return (header + footer).decode("utf-8")
Beispiel #4
0
 def derive_source_filesystem_id(self, source_passphrase: "DicewarePassphrase") -> str:
     scrypt_for_filesystem_id = scrypt.Scrypt(
         length=64,
         salt=self._salt_for_filesystem_id,
         n=self._scrypt_n,
         r=self._scrypt_r,
         p=self._scrypt_p,
         backend=self._backend,
     )
     hashed_passphrase = scrypt_for_filesystem_id.derive(source_passphrase.encode("utf-8"))
     return b32encode(hashed_passphrase).decode("utf-8")
Beispiel #5
0
 def _scrypt_hash(self, password: str, salt: bytes) -> bytes:
     backend = default_backend()
     scrypt_instance = scrypt.Scrypt(
         length=64,
         salt=salt,
         n=2**14,
         r=8,
         p=1,
         backend=backend,
     )
     return scrypt_instance.derive(password.encode("utf-8"))
Beispiel #6
0
def authenticate_user_credentials(username, password):
    from cryptography import exceptions

    try:
        import json

        with open("../../db.json", "r") as f:
            data = json.load(f)
            db_user = data["li"]["username"]
            db_pass = data["li"]["password"]
            import mysql.connector

            with mysql.connector.connect(
                    host="localhost",
                    user=db_user,
                    password=db_pass,
                    database="li",
                    raw=True,
            ) as cnx:
                cursor = cnx.cursor()
                cursor.execute(
                    """SELECT salt, hashed_key FROM li_auth WHERE username=%s""",
                    (username, ),
                )
                row = cursor.fetchone()
                if not row:
                    return False
                salt = bytes(row[0])
                hashed_key = bytes(row[1])
                from cryptography.hazmat.primitives.kdf import scrypt

                kdf = scrypt.Scrypt(salt=salt, length=128, n=2**14, r=8, p=1)
                import base64

                kdf.verify(bytes(password, "utf-8"),
                           base64.urlsafe_b64decode(hashed_key))
    except exceptions.InvalidKey:
        return False
    return True
Beispiel #7
0
print("\n\n")
# ******************************************************************************************

# ******************************************************************************************
digest = mypass

print("**** Testing with Scrypt from hazmat...")
# ******** Time **********
start = time.time()

for counter in range(iterations):
    print("Iteration %s from %s..." % (counter + 1, iterations))
    #   digest = scrypt_from_hashlib(password=digest, salt=mysalt, n=memory, r=8, p=1, maxmem=2147483646, dklen=128)
    backend = default_backend()
    kdf = scrypt_from_hazmat.Scrypt(salt=mysalt,
                                    length=128,
                                    n=memory,
                                    r=8,
                                    p=1,
                                    backend=backend)
    digest = kdf.derive(digest)

# ******** Time **********
end = time.time()
print("*** Time: ", end - start,
      "**********************************************")
print("Digest in base64 format:", binascii.b2a_base64(digest).decode("utf-8"))

print("\n\n")
# ******************************************************************************************