Last active
October 17, 2020 12:43
-
-
Save Owez/b857ec315e9cb51eb784bcf0b0416967 to your computer and use it in GitHub Desktop.
Argon2 + api key hashing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// Encodes plaintext with [ARGON_PEPPER] before the salt is added | |
fn encode_pepper<P: Into<String>>(plaintext: P) -> String { | |
format!("{}{}", plaintext.into(), ARGON_PEPPER) | |
} | |
/// Simplifies frontend of [gen_argon_hash] + [encode_hash_base64] into | |
/// a single function that only returns completed, [String]ified hash, typically | |
/// used for comparisons with already made hashes | |
pub fn hash_plaintext<P: Into<String>, S: Into<Option<i64>>>( | |
password: P, | |
existing_salt: S, | |
) -> String { | |
encode_hash_base64(&gen_argon_hash(password, existing_salt).0) | |
} | |
/// Generates an argon2 hash from given `password` and generates a new salt | |
/// automatically, returning the salt used. | |
/// | |
/// If inputted `existing_salt` is an [Option::Some], this function will instead use that salt | |
/// | |
/// Will always put a pepper in the form of [ARGON_PEPPER] before the salt, being | |
/// as such: `[password][pepper][salt]` in that order | |
pub fn gen_argon_hash<P: Into<String>, S: Into<Option<i64>>>( | |
password: P, | |
existing_salt: S, | |
) -> ([u8; 32], i64) { | |
let peppered_password = encode_pepper(password); | |
let salt = existing_salt | |
.into() | |
.map_or_else(|| rand::rngs::OsRng.gen(), |s| s); | |
let argon_res = argon2rs::argon2i_simple(&peppered_password, &base64::encode(salt.to_string())); | |
(argon_res.to_owned(), salt) | |
} | |
/// Converts a raw password hash of `[u8; 32]` to a string for use in easily | |
/// storing inside of database and such | |
pub fn encode_hash_base64(hash: &[u8; 32]) -> String { | |
let mut encoded_hash = String::new(); | |
base64::encode_config_buf(hash, base64::STANDARD, &mut encoded_hash); | |
encoded_hash | |
} | |
/// Generates a new 128-bit api key similarly to how [hash_plaintext] works but | |
/// with a heavier salt. Works by combining two cryptographically secure u128 | |
/// nums together then encoding in base64 then adding id to front, hashing and | |
/// base64 encoding once more | |
pub fn gen_api_key(id: i32) -> String { | |
let gen_plain_salt = || -> [u8; 16] { rand::rngs::OsRng.gen::<u128>().to_be_bytes() }; | |
let mut full_salt = gen_plain_salt().to_vec(); | |
full_salt.append(&mut gen_plain_salt().to_vec()); | |
base64::encode(argon2rs::argon2i_simple( | |
&id.to_string(), | |
&base64::encode(full_salt), | |
)) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment