Exemple #1
0
 def test_hash_fast(self, password):
     """
     Hash various passwords as cheaply as possible.
     """
     hash_password(
         password,
         salt=b"12345678",
         time_cost=1,
         memory_cost=8,
         parallelism=1,
         hash_len=8,
     )
Exemple #2
0
 def test_hash_fast(self, password):
     """
     Hash various passwords as cheaply as possible.
     """
     hash_password(
         password,
         salt=b"12345678",
         time_cost=1,
         memory_cost=8,
         parallelism=1,
         hash_len=8,
     )
Exemple #3
0
 def test_random_salt(self):
     """
     Omitting a salt, creates a random one.
     """
     rv = hash_password(b"secret")
     salt = rv.split(b",")[-1].split(b"$")[1]
     assert (
         # -1 for not NUL byte
         int(_encoded_str_len(DEFAULT_RANDOM_SALT_LENGTH)) - 1 == len(salt))
Exemple #4
0
 def test_random_salt(self):
     """
     Omitting a salt, creates a random one.
     """
     rv = hash_password(b"secret")
     salt = rv.split(b",")[-1].split(b"$")[1]
     assert (
         # -1 for not NUL byte
         int(_encoded_str_len(DEFAULT_RANDOM_SALT_LENGTH)) - 1 == len(salt)
     )
Exemple #5
0
def _create_test_user(sql):
    """quick and dirty way to create a user to test logging in with.

    email: [email protected]
    password: hunter2
    """
    sql(
        "INSERT INTO users (name, email, password) VALUES ('test user', "
        "'*****@*****.**', :password)",
        password=argon2.hash_password(b"hunter2").decode(),
    )
Exemple #6
0
    def test_hash_password(self, type, hash):
        """
        Creates the same encoded hash as the Argon2 CLI client.
        """
        rv = hash_password(
            TEST_PASSWORD,
            TEST_SALT,
            TEST_TIME,
            TEST_MEMORY,
            TEST_PARALLELISM,
            TEST_HASH_LEN,
            type,
        )

        assert hash == rv
        assert isinstance(rv, bytes)
Exemple #7
0
    def test_hash_password(self, type, hash):
        """
        Creates the same encoded hash as the Argon2 CLI client.
        """
        rv = hash_password(
            TEST_PASSWORD,
            TEST_SALT,
            TEST_TIME,
            TEST_MEMORY,
            TEST_PARALLELISM,
            TEST_HASH_LEN,
            type,
        )

        assert hash == rv
        assert isinstance(rv, bytes)
Exemple #8
0
 def test_illegal_argon2_parameter(self):
     """
     Raises HashingError if hashing fails.
     """
     with pytest.raises(HashingError):
         hash_password(TEST_PASSWORD, memory_cost=1)
Exemple #9
0
 def test_hash_wrong_arg_type(self):
     """
     Passing an argument of wrong type raises TypeError.
     """
     with pytest.raises(TypeError):
         hash_password(u"oh no, unicode!")
Exemple #10
0
 def test_hash_defaults(self):
     """
     Calling without arguments works.
     """
     hash_password(b"secret")
Exemple #11
0
 def test_hash_wrong_arg_type(self):
     """
     Passing an argument of wrong type raises TypeError.
     """
     with pytest.raises(TypeError):
         hash_password(u"oh no, unicode!")
Exemple #12
0
 def test_hash_defaults(self):
     """
     Calling without arguments works.
     """
     hash_password(b"secret")
Exemple #13
0
 def test_illegal_argon2_parameter(self):
     """
     Raises HashingError if hashing fails.
     """
     with pytest.raises(HashingError):
         hash_password(TEST_PASSWORD, memory_cost=1)
Exemple #14
0
def add_user(username: str, password: bytes, level=500):
    passwd = argon2.hash_password(password, secrets.token_bytes(None))
    user = Users(username, passwd, level)
    db.session.add(user)
    db.session.commit()
Exemple #15
0
    def add(username, original_password, display_name, plain_text=True):
        Global.cursor.execute(
            "SELECT TRUE FROM Account WHERE username = %s",
            (username,)
        )
        if len(Global.cursor.fetchall()) > 0:
            error_message = "user \"" + username + "\" already exists"
            logging.error(error_message)
            return False, error_message
        salt = secrets.token_hex(int(16/2)) ## each byte gets converted to two hex digits
        sha_function = Global.config.get("miscellaneous", "sha_function")
        if sha_function.upper().startswith("SHA3"):
            hash_function = getattr(hashlib, sha_function.lower().replace("-", "_"))
        else:
            hash_function = getattr(hashlib, sha_function.lower().replace("-", ""))
        if plain_text:
            hashed_password = hash_function(original_password.encode(Global.encoding)).hexdigest()
        else:
            hashed_password = original_password
        salt_method = Global.config.get("miscellaneous", "salt_method")
        try:
            if salt_method.upper().startswith("SHA"):
                hash = hash_function(hashed_password.encode(Global.encoding) + salt.encode(Global.encoding)).hexdigest()
                Global.cursor.execute(
                    "INSERT INTO Account (username, displayName, salt, hash) VALUES (%s, %s, %s, %s);",
                    (username, display_name, salt, hash)
                )
            elif salt_method.lower() == "argon2":
                ## https://argon2-cffi.readthedocs.io/en/stable/argon2.html
                ## don't change type because Type.ID is the most secure, other parameters may be changed without resetting/migrating the database
                hash = argon2.hash_password(
                    password=hashed_password.encode(Global.encoding),
                    salt=salt.encode(Global.encoding),
                    time_cost=DEFAULT_TIME_COST,
                    memory_cost=DEFAULT_MEMORY_COST,
                    parallelism=DEFAULT_PARALLELISM,
                    hash_len=DEFAULT_HASH_LENGTH,
                    type=Type.ID,
                ).decode(Global.encoding)
                Global.cursor.execute(
                    "INSERT INTO Account (username, displayName, hash) VALUES (%s, %s, %s);",
                    (username, display_name, hash)
                )
            else:
                logging.critical("Salt method is invalid.")
                raise Exception
        except mysql.connector.DataError as e:
            ## db.rollback() if one of many commits fail (ACID property)
            assert "data too long" in e.msg.lower()
            error_message = "username must be 15 or less characters"
            logging.error(error_message)
            return False, error_message

        print()
        logging.debug("Added new account to database:")
        logging.debug("  Username: "******"  Password: "******"  Hashed Password: "******"argon2":
            logging.debug("  Salt: " + salt)
        else:
            logging.debug("  Embedded Salt: " + salt)
        logging.debug("  Hash: " + hash)
        print()

        return True, ""