Skip to content

Password hashing

Password hashing transforms a password into an encoded value that you can store and check later. The application keeps that hash and verifies each candidate through check(). This process lets it check a password without providing an operation to recover it.

Orionis exposes this service through the Hash facade and IHashManager contract. The default driver is argon2, which generates Argon2id hashes; bcrypt is also included. Both run their calculations on a worker thread so make() and check() can be used from asynchronous actions.

NeedServiceResult
Store a password and check future attemptsHashEncoded hash containing the algorithm, parameters and salt.
Keep text that your application must recoverCryptEncrypted payload requiring the application key for decryption.

The encryption guide explains the second case. Base64 encoding represents data but does not protect it on its own.

The APP_KEY key belongs to encryption. Hashing drivers use their own parameters and the salt generated by their backend; you do not supply a salt and they do not use that application key to check passwords.

OperationUse
await Hash.make(password)Generates the hash to store in the user’s record.
await Hash.check(candidate, stored_hash)Checks a candidate against the stored hash and returns bool.
Hash.needsRehash(stored_hash)Checks whether the hash needs upgrading according to the current driver and parameters.
Hash.driver("bcrypt")Explicitly selects a hasher when you know a record’s algorithm.

Import the facade with from orionis.support.facades import Hash. Calculation operations require await; needsRehash() and driver() are synchronous after application boot. You can also inject IHashManager from orionis.hashing.contracts into a constructor or action.

The built-in provider registers the service during Orionis boot. Examples in the practical guide use a real application, HTTP schemas and controllers; you do not need to create a hash manager for every request.

  1. Validate the received data and password policy.
  2. Generate the hash with await Hash.make(...).
  3. Store the complete result in the password field.
  4. On a subsequent attempt, retrieve the stored hash.
  5. Check the candidate with await Hash.check(candidate, stored_hash).
  6. If verification succeeds and needsRehash() requests it, generate a replacement from the verified password and persist it.
flowchart TD
    accTitle: Checking and upgrading a password
    A["Candidate and stored hash"] --> B["Select the corresponding hasher"]
    B --> C["await check"]
    C --> D{"Matches"}
    D -- No --> E["Reject the attempt without changing the hash"]
    D -- Yes --> F{"needsRehash"}
    F -- No --> G["Continue the authentication flow"]
    F -- Yes --> H["await make with the verified password"]
    H --> I["Persist the replacement hash"]
    I --> G

Two make() calls for the same password can produce different hashes because they include a random salt. Use check() to verify it; directly comparing a newly generated hash with the stored one does not implement that process.

needsRehash() inspects format and costs; it neither verifies the user nor modifies the database. The hashing manager also does not register accounts, create sessions or limit attempts. To implement login through framework guards, continue with authentication.

DriverGenerated algorithmMain configuration
argon2argon2idMemory in KiB, parallelism and iterations.
bcryptbcryptThe rounds cost factor.

config/hashing.py selects the driver and costs. Changing HASH_DRIVER affects operations using the default; it does not convert existing hashes or make check() automatically detect other algorithms.

The generation and verification guide covers:

  • Registration and verification from controllers.
  • Facade access and constructor or method injection.
  • Every config/hashing.py option and its environment variables.
  • Per-call costs, algorithm inspection and available setters.
  • Rehashing after successful verification and explicit migration from bcrypt.
  • Dependencies, exceptions and driver limits.

For recoverable values and their keys, see data encryption.