Estou usando esta biblioteca Argon2 em Rust para hash de senha:
https://docs.rs/argon2/latest/argon2/
let salt = SaltString::generate(&mut OsRng);
let argon2 = Argon2::default();
let password_bytes = form.password.as_bytes();
let password_hash = argon2.hash_password(&password_bytes, &salt).unwrap().to_string();
println!("password_hash: {}",password_hash);
let parsed_hash = PasswordHash::new(&password_hash).unwrap();
if Argon2::default().verify_password(&password_bytes, &parsed_hash).is_ok() {
println!("Valid!");
}
O password_hash
gerado se parece com isso:
$argon2id$v=19$m=19456,t=2,p=1$UWyFFxDMETxLo1q7BFjIEQ$i3MwCW0H7fZjFG7hMwKAPZgWs4hjo/foEUCwLsqp9uY
Parece sempre ter o prefixo$argon2id$v=19$m=19456,t=2,p=1$
Posso remover esse prefixo antes de armazená-lo no banco de dados para economizar espaço? E então apenas codificá-lo para adicioná-lo antes de verificar?
O que essas coisas significam?
Será sempre a mesma coisa?
Os algoritmos modernos de hash de senha contêm "parâmetros de custo" que negociam desempenho contra segurança. Em termos simples, você quer que a verificação do hash seja lenta demais para que um invasor tente várias senhas possíveis, mas rápida o suficiente para que um usuário legítimo não pense que seu aplicativo está quebrado.
Para gerar um hash correspondente quando a senha correta é fornecida, você precisa saber os parâmetros exatos usados para gerar o hash armazenado. Como você disse, você pode codificar esses parâmetros, mas isso significa que você nunca pode alterá-los - em particular, conforme os computadores ficam mais rápidos, você quer que seu hash fique mais lento.
Então, a prática comum é armazenar os parâmetros usados junto com cada hash; então, se você alterá-los para novos hashes, você ainda pode verificar os hashes antigos. Algumas bibliotecas também permitem que você verifique se o hash armazenado usa os valores atualizados para os parâmetros sempre que o usuário faz login - enquanto você tem a senha correta, você pode salvar um novo hash mais seguro.
Da mesma forma, algoritmos de hash às vezes são encontrados quebrados, ou simplesmente se tornam muito fáceis para invasores usarem força bruta. Nesse ponto, você pode querer mudar do Argon2 para algo completamente diferente. Novamente, você precisa saber quais dos seus hashes armazenados estão usando o Argon2, e quais estão usando o novo algoritmo, então a prática comum é indicar o algoritmo usado bem no começo do hash.
Para o Argon2, o formato desses parâmetros é, na verdade, parte do padrão publicado, então todas as implementações do Argon2 gerarão, e esperarão, esses prefixos exatos. Embora você possa retirá-los, há realmente muito pouco a ganhar fazendo isso, e muito a perder.
Quanto ao que os parâmetros realmente significam , você pode encontrar um breve resumo na documentação do Rust que você vinculou, especificamente na
argon2::Params
struct :m_cost
: tamanho da memória em blocos de 1 KiB. Entre8*p_cost
e(2^32)-1
.t_cost
: número de iterações. Entre1
e(2^32)-1
p_cost
: grau de paralelismo. Entre1
e(2^24)-1
.