Rust DjangoHashers

A Rust port of the password primitives used in alternatice implementation: the package library that requires OpenSSL

Rust DjangoHashers

A Rust port of the password primitives used in Django Project.

Django's django.contrib.auth.models.User class has a few methods to deal with passwords, like set_password() and check_password(); DjangoHashers implements the primitive functions behind those methods. All Django's built-in hashers are supported.

This library was conceived for Django integration, but is not limited to it; you can use the password hash algorithm in any Rust project (or FFI integration), since its security model is already battle-tested.

TL;DR

Content of examples/tldr.rs:

Output:

Installation

Add the dependency to your Cargo.toml:

Reference and import:

Compiling Features

New in 0.3.0.

By default all the hashers are enabled, but you can pick only the hashers that you need to avoid unneeded dependencies.

  • default: all hashers.
  • with_pbkdf2: only PBKDF2 and PBKDF2SHA1.
  • with_argon2: only Argon2.
  • with_scrypt: only Scrypt. (new in 1.5.0)
  • with_bcrypt: only BCrypt and BCryptSHA256.
  • with_legacy: only SHA1, MD5, UnsaltedSHA1, UnsaltedMD5 and Crypt.
  • fpbkdf2: enables Fast PBKDF2 (requires OpenSSL, see below).
  • fuzzy_tests: only for development, enables fuzzy tests.

Fast PBKDF2 Version

Depending on your platform, OS and version of libraries, it is possible that DjangoHashers can be slower than Python/Django's reference implementation. If performance is critical for your case, there is an alternatice implementation: the package fastpbkdf2 uses a C-binding of a library that requires OpenSSL. If ring's implementation of PBKDF2 reaches this level of optiomization, the fastpbkdf2 version will be deprecated.

Installation

Add the dependency to your Cargo.toml declaring the feature:

You need to install OpenSSL and set the environment variable to make it visible to the compiler; this changes depending on the operation system and package manager, for example, in macOS you may need to do something like this:

For other OSs and package managers, follow the guide of how to install Python’s Cryptography dependencies, that also links against OpenSSL.

Performance

On a Quad-Core Intel Core i7:

Method Encode or Check Performance
Django 4.0.1 on Python 3.10.1 153ms 100% (baseline)
djangohashers with ring::pbkdf2 (default) 162ms 105.9% 🐢
djangohashers with fastpbkdf2 95ms 62.1% 🐇

On a Apple M1:

Method Encode or Check Performance
Django 4.0.1 on Python 3.10.1 57ms 100% (baseline)
djangohashers with ring::pbkdf2 (default) 30ms 52.6% 🐇
djangohashers with fastpbkdf2 21ms 36.8% 🐇

Replicate test above with Docker:

Compatibility

DjangoHashers passes all relevant unit tests from Django 1.4 to 4.1, there is even a line-by-line translation of tests/auth_tests/test_hashers.py.

What is not covered:

  • Upgrade/Downgrade callbacks.
  • Any 3rd-party hasher outside Django's code.
  • Some tests that makes no sense in idiomatic Rust.

Usage

API Documentation, thanks to docs.rs project!

Verifying a Hashed Password

Function signatures:

Complete version:

Possible Errors:

  • HasherError::UnknownAlgorithm: anything not recognizable as an algorithm.
  • HasherError::BadHash: Hash string is corrupted.
  • HasherError::InvalidIterations: number of iterations is not a positive integer.
  • HasherError::EmptyHash: hash string is empty.
  • HasherError::InvalidArgon2Salt: Argon2 salt should be Base64 encoded.

If you want to automatically assume all errors as "invalid password", there is a shortcut for that:

Generating a Hashed Password

Function signatures:

Available algorithms:

  • Algorithm::PBKDF2 (default)
  • Algorithm::PBKDF2SHA1
  • Algorithm::Argon2
  • Algorithm::Scrypt
  • Algorithm::BCryptSHA256
  • Algorithm::BCrypt
  • Algorithm::SHA1
  • Algorithm::MD5
  • Algorithm::UnsaltedSHA1
  • Algorithm::UnsaltedMD5
  • Algorithm::Crypt

The algorithms follow the same Django naming model, minus the PasswordHasher suffix.

Using default settings (PBKDF2 algorithm, random salt):

Using a defined algorithm (random salt):

Using a defined algorithm and salt (not recommended, use it only for debug):

Warning: make_password_with_settings and make_password_core will both panic if salt is not only letters and numbers (^[A-Za-z0-9]*$).

Generating a Hashed Password based on a Django version

New in 0.2.1.

Django versions can have different number of iterations for hashers based on PBKDF2 and BCrypt algorithms; this abstraction makes possible to generate a password with the same number of iterations used in that versions.

Available versions:

  • DjangoVersion::CURRENT Current Django version (4.0 for DjangoHashers 1.5.0).
  • DjangoVersion::V1_4 Django 1.4
  • DjangoVersion::V1_5 Django 1.5
  • DjangoVersion::V1_6 Django 1.6
  • DjangoVersion::V1_7 Django 1.7
  • DjangoVersion::V1_8 Django 1.8
  • DjangoVersion::V1_9 Django 1.9
  • DjangoVersion::V1_10 Django 1.10
  • DjangoVersion::V1_11 Django 1.11
  • DjangoVersion::V2_0 Django 2.0
  • DjangoVersion::V2_1 Django 2.1
  • DjangoVersion::V2_2 Django 2.2
  • DjangoVersion::V3_0 Django 3.0
  • DjangoVersion::V3_1 Django 3.1
  • DjangoVersion::V3_2 Django 3.2
  • DjangoVersion::V4_0 Django 4.0
  • DjangoVersion::V4_1 Django 4.1

Verifying a Hash Format (pre-crypto)

Function signature:

You can check if the password hash is properly formatted before running the expensive cryto stuff:

Contributing

  • Be patient with me, I’m new to Rust and this is my first project.
  • Don't go nuts with your mad-rust-skillz, legibility is a priority.
  • Please use rustfmt in your code.
  • Always include some test case.

License

Rust DjangoHashers is released under the 3-Clause BSD License.

tl;dr: "free to use as long as you credit me".

Versions

Find the latest versions by id

Information - Updated Apr 21, 2022

Stars: 50
Forks: 5
Issues: 0

Freepass is an example password manager in rust

There is an export command in the CLI that produces CSV suitable for import into Bitwarden

Freepass is an example password manager in rust

Rust bindings for libinjection

Add libinjection to dependencies of Cargo

Rust bindings for libinjection

Rust bindings for the C++ api of PyTorch

LIghtweight wrapper for pytorch eg libtorch in rust

Rust bindings for the C++ api of PyTorch

A Rust implementation of the Master Password algorithm, created for freepass

A Master Password algorithm, created for secstr secure strings and sodiumoxide's underlying libsodium-sys

A Rust implementation of the Master Password algorithm, created for freepass

This is a purely Rust-based library that provides both variants of the

state-of-the-art Argon2 hashing algorithm, suitable for password hashing and

This is a purely Rust-based library that provides both variants of the

rust-keylock is a password manager and its goals are to be:

The core logic is written in Diceware

rust-keylock is a password manager and its goals are to be:

A Password Manager for NanoS, written in Rust

A simple password manager application for NanoS, with command-line interface

A Password Manager for NanoS, written in Rust

Ruo is a dictionary-based password cracker written in rust 🦀

The primary purpose is to crack weak hashes/commonly used passwords

Ruo is a dictionary-based password cracker written in rust 🦀

A simple static password generator for rust

I recently picked up a Yubikey Personalization Tool doesn't include a tool to auto-generate a strong password

A simple static password generator for rust

Password Generator - Made with Rust

Rust beginner here, wanted to make this as my first Rust project!

Password Generator - Made with Rust

WASM rust the ripper

Password cracker made in WASM Rust, inspired by the popular John the Ripper

WASM rust the ripper
Facebook Instagram Twitter GitHub Dribbble
Privacy