Functional Weave
Code in Rust

auth.password-hash@1.0.0

impl/python/hash_password.py

1,184 bytes · the Python implementation · view raw

Imports name this capability’s declared dependencies, which fune builds next to it in your project; each one links to its page.

from typing import Sequence

from .crypto_pbkdf2_sha256 import pbkdf2_sha256  ← from crypto.pbkdf2-sha256 ^1.0.0 · built alongside by fune
from .encoding_base64_base64_encode import base64_encode
from .encoding_utf8_utf8_encode import utf8_encode


def hash_password(password: str, salt: Sequence[int], iterations: int) -> str:
    """A password as pbkdf2_sha256$<iterations>$<salt>$<hash>.

    The salt is passed in because a capability may not read randomness:
    pass list(secrets.token_bytes(16)) (or the bytes themselves), fresh for
    every call.
    """
    if not isinstance(password, str):
        raise TypeError("password must be a string")
    if isinstance(salt, (str, dict)) or not hasattr(salt, "__len__"):
        raise TypeError("salt must be a list of integers from 0 to 255")
    if len(salt) < 16:
        raise ValueError("salt must be at least 16 bytes, received %d" % len(salt))
    if isinstance(iterations, bool) or not isinstance(iterations, int) or iterations < 1000:
        raise ValueError("iterations must be a whole number of at least 1000")
    derived = pbkdf2_sha256(utf8_encode(password), salt, iterations, 32)
    return "pbkdf2_sha256$%d$%s$%s" % (iterations, base64_encode(salt), base64_encode(derived))