Password hashing functions / KDFs

Overview

RustCrypto: Password Hashes

Project Chat dependency status Apache2/MIT licensed

Collection of password hashing algorithms, otherwise known as password-based key derivation functions, written in pure Rust.

Supported Algorithms

Algorithm Crate Crates.io Documentation MSRV
Argon2 argon2 crates.io Documentation MSRV 1.51
bcrypt-pbkdf bcrypt-pbkdf crates.io Documentation MSRV 1.51
PBKDF2 pbkdf2 crates.io Documentation MSRV 1.51
scrypt scrypt crates.io Documentation MSRV 1.51
SHA-crypt sha-crypt crates.io Documentation MSRV 1.51

Please see the OWASP Password Storage Cheat Sheet for assistance in selecting an appropriate algorithm for your use case.

Minimum Supported Rust Version (MSRV) Policy

MSRV bumps are considered breaking changes and will be performed only with minor version bump.

License

All crates licensed under either of

at your option.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

Comments
  • Balloon implementation

    Balloon implementation

    See #1.

    There are a lot of small open questions, but the really important ones that need to be answered are:

    • [x] I don't know what ints_to_block is supposed to be (https://github.com/RustCrypto/password-hashes/pull/232#discussion_r700919220)
    • [x] to_int is unclear (https://github.com/RustCrypto/password-hashes/pull/232#discussion_r700925129)
    • [x] The paper uses a || operator to describe modifying the salt for parallel execution, I don't know what this is (https://github.com/RustCrypto/password-hashes/pull/232#discussion_r700934385)
    • [x] cnt can overflow, the paper and the reference implementation say nothing about that (https://github.com/RustCrypto/password-hashes/pull/232#discussion_r700937948)
    • [x] I'm hashing u32 values, the reference implementation uses i32 (I think), the paper says nothing about it (https://github.com/RustCrypto/password-hashes/pull/232#discussion_r700945238)
    • [x] The paper doesn't specify a default configuration (https://github.com/RustCrypto/password-hashes/pull/232/files#r700980909)

    For reference:

    • The paper: https://eprint.iacr.org/2016/027.pdf
    • Reference (actually they call it prototype) implementation: https://github.com/henrycg/balloon/
    opened by daxpedda 23
  • argon2: Add tests from reference implementation

    argon2: Add tests from reference implementation

    Hi !

    I tried to add the tests from the argon2 reference implementation as suggested in #109

    It's not finished, but I'd like to have some pointers there 😃

    Most (but not all !) tests involving argon2i are falling on ctx.verify_password (but hash_password_into returns the correct hash). On the other hand argon2id tests are passing, so I guess the issue comes from the way I use verify_password...

    On top of that I'm not sure how to implement the test related to the encoding errors (see commented part of the code): In the reference implementation, test are done to check the hash function detect incorrect hash encoding. However this doesn't work given PasswordHash::new does the parsing and is ok with missing fields.

    See for instance the reference_argon2i_invalid_encoding_1 test that provide an encoded hash with a missing $, we end up with:

    PasswordHash { algorithm: Ident("argon2i"), version: None, params: {Ident("m"): Value("65536"), Ident("t"): Value("2"), Ident("p"): Value("1c29tZXNhbHQ")}, salt: Some(Salt("9sTbSlTio3Biev89thdrlKKiCaYsjjYVJxGAL3swxpQ")), hash: None }
    

    But argon doesn't seem to complain (even from the p=1c29tZXNhbHQ !)

    I also don't understand how to use the t/p/m configuration coming from the encoded hash: it seems incredibly cumbersome to have to use ParamsBuilder in conjunction with the PasswordHash object to manually extract and validate parameters...

    anyway I waiting for your feedback ;-)

    opened by touilleMan 15
  • Consider adding algorithm primers

    Consider adding algorithm primers

    I'm writing a server boilerplate that I hope to eventually use in production, right now it's just for fun. One of the things I'd like to do is store user accounts (and password digests!) in my database.

    I noticed y'all have three algorithms listed but no guidance about how to choose one for the naive 🙋‍♂️ . Would it be reasonable to provide a primer about each algorithm and what settings it might be appropriate it?

    opened by cbzehner 12
  • Bug in pbkdf2 xor function

    Bug in pbkdf2 xor function

    Currently the XOR function checks if the salt lenght is greater than or equal to itself:

    [inline(always)]
    fn xor(res: &mut [u8], salt: &[u8]) {
        assert!(salt.len() >= salt.len(), "length mismatch in xor");
        for i in 0..res.len() {
            res[i] ^= salt[i];
        }
    }
    

    I believe it actually should be checking that it's greater than or equal to res. Currently this doesn't show up in tests because the salt value is always passed with an F::OutputSize length and chunk will always be <= F::OutputSize, but I think this should be fixed in case the implementation changes in the future. I've checked the versions available on crates.io(0.1.0, 0.2.0, 0.2.1), too see if they all are implemented in a way that chunk will never be greater in length than a salt value passed. I found no problems with these three versions, but they all have this exact assert! line. I have also added regression tests to this PR.

    opened by brycx 9
  • Argon2 refactor

    Argon2 refactor

    Practically a rewrite of the argon2 crate.

    Summary of changes:

    • Parallel implementation is safer by not creating mutable aliases of self, but instead separating lanes into a mutable slice (current segment) and 2 immutable slices (before and after the segment).
    • The Instance struct has been merged with the Argon2 struct since it was basically just a copy of it.
    • The Argon2 struct has a new method, fill_memory, which omits the calculation of a hash. This is used in e.g. RandomX.
    • Methods on ParamsBuilder don't return Results anymore and take self by reference to make it more ergonomic.
    opened by Pjottos 8
  • wip: add sha256-crypt

    wip: add sha256-crypt

    This does not yet work correctly. It fails some tests because the b64-functions don't work. One byte is always wrong. I triple-checked that I translated the table in https://akkadia.org/drepper/SHA-crypt.txt correctly (search for "base-64 encoded final C digest"). Unfortunately, I cannot find the error in the algorithm.

    I would appreciate some help.

    I will also have a look if it's possible to refactor the implementations so they share more code.

    opened by ibotty 7
  • argon2: Add parallel lane processing

    argon2: Add parallel lane processing

    Adds parallel processing for lanes Closes #103

    The parallelism is gated behind the feature parallel

    When the feature is activated, the #![forbid(unsafe_code)] gets downgraded to #![deny(unsafe_code)] due to unsafe usage (here)
    The #![no_std] flag is being disabled as well

    opened by aumetra 7
  • Document rscrypt format upgrade path

    Document rscrypt format upgrade path

    It seems that starting with scrypt 0.6.0, "rscrypt" format is no longer supported?

    I cannot find any documentation on how to upgrade existing hashes, as they don't seem to be supported anymore.

    opened by ashaduri 6
  • Make easier to support multiple algos?

    Make easier to support multiple algos?

    I try to support the selection of many algorithms to store passwords (like in django) and found it not as easy to do it. This crate has all in a workspace but not a way to select a group alike:

    # Ideally:
    password-hash = { version = "*",  features = ["argon2", "scrypt"] }
    
    # Today
    # All sub-crate reexport dependencies, so I need to manually re-add all?
    argon2 = { version = "0.3", features = ["std"] ,  optional=true}
    scrypt = {version = "0.8.0",  optional=true"}
    
    # So I can do things generically...
    password-hash = "*"
    rand-core = "*"
    
    opened by mamcx 6
  • [Q] High CPU usage

    [Q] High CPU usage

    Hi there,

    first of all: thank you for the nice crate!

    But there is one thing that I don't get. I've used an scrypt implementation in Java with the same provided settings as you have mentioned in the documentation (15, 8, 1). The Java implementation is using a lot of memory and some CPU resources. This is what I expected with the given settings. When I use the rust version it will consume a lot of CPU, but almost no RAM.

    I've setup a load test that will create millions of scrypt hashes and the application is just consuming around 60-80m RAM, but ~1600MHz. Just for the comparison the Java version with almost the same settings consumes 1500m RAM and ~800MHz.

    I am using the simple_crypt() function.

    Thank you for any kind of response/help :)

    opened by dweidenfeld 6
  • Argon2

    Argon2

    Translation of the CC0-licensed reference implementation as implemented in C, as of this commit:

    commit 440ceb9612d5a20997e3e12728542df2de713ca4 Merge: 3df7b84 6d86209 Author: Dmitry Khovratovich [email protected] Date: Thu Jul 9 14:56:35 2020 +0200

    This translation is based on the reference implementation (ref.c) as opposed to the optimized implementation (opt.c) to get to a baseline implementation which passed the test vectors, but it would probably be best to translate the optimized implementation.

    Multithreading is also unimplemented.

    Otherwise, (if it were working) this implementation provides Argon2d, Argon2i, and Argon2id along with support for versions 0x10 and 0x13.

    opened by tarcieri 5
  • implement password_hash's traits for sha_crypt

    implement password_hash's traits for sha_crypt

    Is there any reason (except that they should not to be used for new code) not to implement the password_hash's traits?

    Maybe marked with deprecated attribute to not be used.

    opened by ibotty 1
  • Evaluate tobtu.com minimum password settings recommendations

    Evaluate tobtu.com minimum password settings recommendations

    This guide enumerates the minimum settings required to slow attackers to <10 kH/s/GPU (using RTX 3080 or RX 6800 XT as reference GPUs) for various algorithms we implement:

    https://tobtu.com/minimum-password-settings/

    It might be a good idea to incorporate them into our documentation and/or use them to inform our recommendations/defaults.

    Argon2

    • Argon2{id,d}: m=44*1024 (44 MiB), t=1, p=1
    • Argon2{id,d}: m=18*1024 (18 MiB), t=2, p=1
    • Argon2: m=11*1024 (11 MiB), t=3, p=1
    • Argon2: m=8*1024 (8 MiB), t=4, p=1
    • Argon2: m=7*1024 (7 MiB), t=5, p=1

    In general:

    Argon2i: m≥89062.5/(3*t-1)*α, t≥3, p=1 Argon2{id,d}: m≥89062.5/(3*t-1)*α, t≥1, p=1 RTX 3080 12GB memory bandwidth: 89,062.5 = 912,000,000,000/10,000/1024 For low memory usage (≲64 MiB) α≈95%. Once memory usage is high enough α drops proportional to memory increase.

    scrypt

    • N=2^17 (128 MiB), r=8, p=1
    • N=2^16 (64 MiB), r=8, p=2
    • N=2^15 (32 MiB), r=8, p=3
    • N=2^14 (16 MiB), r=8, p=5
    • N=2^13 (8 MiB), r=8, p=9

    In general:

    scrypt: N≥570000/r/p*α, r=8, p≥1 RTX 3080 12GB memory bandwidth: 570,000 = 912,000,000,000/10,000/128/1.25 For low memory usage (≲64 MiB) α≈95%. Once memory usage is high enough α drops proportional to memory increase.

    PBKDF2

    • PBKDF2-HMAC-SHA512: 130,000 iterations (Based on RTX 3080 12GB)
    • PBKDF2-HMAC-SHA256: 350,000 iterations (Based on RX 6800 XT)
    • PBKDF2-HMAC-SHA1: 860,000 iterations (Based on RX 6800 XT)
    opened by tarcieri 0
  • Setting the generated hash length for Scrypt

    Setting the generated hash length for Scrypt

    Hey all 👋 I've been using the scrypt package from RustCrypto in a project but recently I hit a small roadblock since I can't seem to find any way of setting the generated hash's length within the module.

    Is there a way of doing this? and if not could I help with implementing a way?

    Thanks in advance, Bradley Schofield

    opened by PineappleIOnic 1
  • argon2: The documentation claims that associated data (and keyid) are deprecated but they are not

    argon2: The documentation claims that associated data (and keyid) are deprecated but they are not

    Currently, the documentation https://docs.rs/argon2/0.3.2/argon2/struct.Params.html#method.data claims that:

    This field is not longer part of the argon2 standard (see: https://github.com/P-H-C/phc-winner-argon2/pull/173), and should not be used for any non-legacy work.

    But I don't think that this is true. Notably, the referenced pull request only talks about the encoding, and the reference implementation still supports associated data: https://github.com/P-H-C/phc-winner-argon2/blob/master/include/argon2.h#L204-L205

    Happily, #247 fixes this by making it possible to set the associated data.

    opened by teythoon 6
  • argon2: std feature pulls in rand number generator

    argon2: std feature pulls in rand number generator

    I'm not sure to what degree this is expected, but if I enable the std feature in argon2, it pulls in a random number generator via getrandom. This is unfortunately not available in all std environments, especially when compiling to Wasm.

    argon2 = { version = "0.3.1", default-features = false, features = ["std"] }
    

    causes a compile fail with target wasm32-unknown-unknown because

    $ cargo tree -i getrandom --target wasm32-unknown-unknown
    getrandom v0.2.3
    └── rand_core v0.6.3
        └── password-hash v0.3.2
            └── argon2 v0.3.1
                └── argon2id-js v0.1.0 (/projects/cosmjs/wasm/argon2id-js)
    

    Seems like password-hash gets pulled in implicitly with default arguments or something like that.

    Adding resolver = "2" does not seems to change things.

    Using alloc instead lets me compile.

    opened by webmaster128 11
Owner
Rust Crypto
Cryptographic algorithms written in pure Rust
Rust Crypto
Rust-based file hashing program

Rash A file hashing tool written in Rust Command line application for calculating the hash value of a file. Rash uses the RustCrypto collection of lib

Stuart Reilly 6 Sep 16, 2022
ASURA implementation in Rust. A better alternative of consistent-hashing.

ASURA implementation in Rust. A better alternative of consistent-hashing.

Akira Hayakawa 4 May 30, 2022
Incremental hashing based on curve25519-dalek

A toy project on building an incremental hash function using the Ristretto elliptic curve for me to learn Rust. Example code from examples/main.rs: us

Alin Tomescu 2 Apr 1, 2022
A fast, non-cryptographic, minimally DoS-resistant hashing algorithm for Rust.

Foldhash This repository contains foldhash, a fast, non-cryptographic, minimally DoS-resistant hashing algorithm implemented in Rust designed for comp

Orson Peters 155 Oct 23, 2024
An implementation of the OPAQUE password-authenticated key exchange protocol

The OPAQUE key exchange protocol OPAQUE is an asymmetric password-authenticated key exchange protocol. It allows a client to authenticate to a server

Novi 178 Jan 9, 2023
Master Password in Pure Rust

Master Password •••| This is the Rust version of the original found here. This can be used as a drop-in replacement for the reference C version, offer

Rust India 34 Apr 13, 2022
A Rust port of the password primitives used in Django Project.

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

Ronaldo Ferreira 52 Nov 17, 2022
The simple password manager for geeks, built with Rust.

Rooster Rooster is a simple password manager for geeks (it works in the terminal). Rooster is made available free of charge. You can support its devel

Conrad Kleinespel 131 Dec 25, 2022
🐴 RusTOTPony — CLI manager of one-time password generators aka Google Authenticator

?? RusTOTPony CLI manager of time-based one-time password generators. It is a desktop alternative for Google Authenticator. Installation Arch Linux Pa

German Lashevich 23 Jan 5, 2023
A safe implementation of the secure remote password authentication and key-exchange protocol (SRP), SRP6a and legacy are as features available.

Secure Remote Password (SRP 6 / 6a) A safe implementation of the secure remote password authentication and key-exchange protocol (SRP version 6a). Ver

Sven Assmann 10 Nov 3, 2022
A simple password manager written in rust

Passman - A password manager written in rust. How to use?: USAGE: passman option Currently available options are: new - initalize passman with a new m

Strawkage 7 Aug 26, 2021
A simple password manager written in Rust

ripasso A simple password manager written in Rust. The root crate ripasso is a library for accessing and decrypting passwords stored in pass format (G

Joakim Lundborg 550 Dec 30, 2022
Ruo is a dictionary-based password cracker written in rust 🦀 .

Ruo is a dictionary-based password cracker written in rust ?? . The primary purpose is to crack weak hashes/commonly used passwords.

Asjid Kalam 10 Mar 6, 2022
A password manager coded in rust

pasman A password manager coded in rust Install Dependency rust Shell git clone https://github.com/AMTitan/pasman.git cd pasman cargo build --release

Arthur Melton 4 Nov 8, 2021
A password entropy calculator.

paspio — pasvorta entropio A (naive) password entropy calculator. Refrain from using this as a sole measure of password strength, it should be used in

Aziz Ben Ali 3 Mar 8, 2022
Password-Authenticated Key Agreement protocols

RustCrypto: PAKEs Password-Authenticated Key Agreement protocols implementation. Warnings Crates in this repository have not yet received any formal c

Rust Crypto 81 Dec 5, 2022
A Rust port of the password primitives used in Django Project.

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

Ronaldo Ferreira 52 Nov 17, 2022
Rest API to check if a password is in a data breach

easypwned (haveibeenpwned / HIBP) Rest API to check if a password is in a data breach. Works offline - everything stays on your machine! Database is i

easybill GmbH 8 Mar 16, 2022
Smarter brute-force password searching for PKZIP encrypted files

Zip Blitz Motivation This program was created for a very specfic problem I had. I had a large encrypted zip file that I lost/forgot the password for.

Michael 4 Jul 29, 2022