1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
//! Passwors is a simple password handling library
//! that utilises Rust's type system to enfore better
//! password handling. Use it as a basic building
//! block for more complex authentication systems.
//!
//! ```rust
//! extern crate passwors;
//!
//! use passwors::*;
//!
//! fn main() {
//! // ... some code...
//!
//! # let some_password_source = "asdf1234 is a really shitty password!".to_owned();
//! // Read a user's password into a clear text password
//! // to generate and compare hashes.
//! let pw = ClearTextPassword::from_string(some_password_source).unwrap();
//! let salt = HashSalt::new().unwrap(); // You should grab this from your database.
//! let a2hash = Argon2PasswordHasher::default();
//! let pw_hash = pw.hash(&a2hash, &salt);
//!
//! # let stored_hash = pw.hash(&a2hash, &salt);
//! // Grab the password hash to compare from your database.
//! // You should always calculate password hashes, even if
//! // the user who wants to log in doesn't exist.
//! assert_eq!(pw_hash, stored_hash, "Login failed!");
//!
//! // ... more code...
//! }
//! ```
//!
//! # The Types
//!
//! There are four types involved when it comes to
//! handling passwords.
//!
//! - `ClearTextPassword` is what you get from a user's
//! inputs. This is a secret token that only its creator
//! should know.
//! - `HashedPassword` is what you use to validate one's
//! identity. It is there to be compared, stored, read,
//! and what not.
//! - `HashSalt` is a blob of random data, generated using
//! strong CSPRNGs only. It should be uniquely generated
//! for each of your users and is used to randomise the
//! outcome of hashing a clear text password.
//! - `PasswordHasher` is a trait for... well... password
//! hashers. They are the only unsafe component here, as
//! they are the only ones that are able to read a user's
//! clear text password.
//!
//! ## Clear Text Password
//!
//! As this is a secret token, this type does not leak any
//! kind of information to anyone but password hashers.
//!
//! - You cannot query the clear text password's length.
//! - You cannot read the clear text password data.
//! - You cannot modify the clear text password.
//! - You cannot compare clear text passwords.
//! - You cannot duplicate clear text passwords.
//! - Additionally, on `drop`, the clear text password's
//! memory will be zero-filled.
//!
//! ## Hashed Password
//!
//! This is what you compare, store into databases,
//! look at, or whatever else. A hashed password is created
//! from a clear text password by giving it a hash salt and
//! a password hasher. Ideally, it is impossible to guess
//! a clear text password by looking at its hash.
//!
//! ## Hash Salt
//!
//! A hash salt should be unique for all users, which is
//! why they are only created using a CSPRNG. You can safely
//! move them around or store them into a data base. But as
//! they should be unique, you cannot clone or copy them.
//!
//! Of course, if you really wanted to have duplicate salts,
//! you could just serialise the same salt for multiple user
//! database entries.
//!
//! ## Password Hasher
//!
//! They are the only ones being able to read clear text
//! passwords. Additionally, the whole security depends on
//! how strong the hash function of choice is. You could,
//! for example, hash the user's passwords using good ol'
//! *MD5*, or you could use *scrypt* instead.
//!
//! Don't forget to store a hasher's configuration next to
//! the user's hashed password in your database, so you can
//! always upgrade your server's hasher settings to fit
//! today's increased computational password cracking power.
extern crate argon2rs;
extern crate serde;
extern crate serde_test;
extern crate test;
extern crate rand;
pub use ClearTextPassword;
pub use HashedPassword;
pub use PasswordHasher;
pub use HashSalt;
pub use CLEAR_TEXT_LEN;
pub use MIN_CLEAR_TEXT_LEN;
pub use HASHED_PASSWORD_LEN;
pub use HASH_SALT_LEN;
pub use ;