Salgar Sua Senha: Melhores Práticas?

Eu sempre fui curioso … Qual é melhor quando salgar uma senha para hashing: prefixo ou postfix? Por quê? Ou isso importa, contanto que você salgue?

Para explicar: Todos nós (sabidamente) sabemos que devemos usar uma senha antes de armazená-la no database. [ Editar: Então você pode evitar coisas como o que aconteceu com Jeff Atwood recentemente ]. Normalmente, isso é feito concatenando o salt com a senha antes de passá-lo pelo algoritmo de hash. Mas os exemplos variam … Alguns exemplos precedem o sal antes da senha. Alguns exemplos adicionam o sal após a senha. Eu já vi alguns que tentam colocar o sal no meio.

Então, qual é o melhor método e por quê? Existe um método que diminui a chance de uma colisão de hash? Meu Google não apresentou uma análise decente sobre o assunto.

Edit: Grandes respostas pessoal! Me desculpe, eu só poderia escolher uma resposta. 🙂

Prefixo ou sufixo é irrelevante, é apenas sobre adicionar alguma entropia e comprimento à senha.

Você deve considerar essas três coisas:

  1. O sal tem que ser diferente para cada senha que você armazena. (Isso é um mal-entendido bem comum)
  2. Use um gerador de números randoms criptograficamente seguro.
  3. Escolha um sal suficientemente longo. Pense no problema do aniversário.

Há uma excelente resposta de Dave Sherohman para outra pergunta: por que você deve usar sais gerados aleatoriamente em vez do nome de um usuário (ou outros dados pessoais). Se você seguir essas sugestões, não importa onde você coloca seu sal.

Eu acho que é tudo semântica. Colocá-lo antes ou depois não importa, exceto contra um modelo de ameaça muito específico.

O fato de estar lá supostamente derrota as tabelas do arco-íris.

O modelo de ameaça ao qual aludi seria o cenário em que o adversário pode ter tabelas de arco-íris de sais comuns acrescentadas / anexadas à senha. (Diga a NSA) Você está adivinhando que eles tenham anexado ou prefixado, mas não ambos. Isso é bobo e é um palpite ruim.

Seria melhor assumir que eles têm a capacidade de armazenar essas tabelas de arco-íris, mas não, digamos, tabelas com sais estranhos intercalados no meio da senha. Nesse caso estreito, eu diria que intercalar seria melhor.

Como eu disse. É semântica. Escolha um sal diferente por senha, um sal longo e inclua caracteres estranhos, como símbolos e códigos ASCII: © ¤¡

A resposta real, que ninguém parece ter tocado, é que ambos estão errados . Se você estiver implementando sua própria criptografia, não importa quão trivial seja sua parte, você cometerá erros.

HMAC é uma abordagem melhor, mas mesmo assim, se você estiver usando algo como SHA-1, você já escolheu um algoritmo que é inadequado para hashing de senha devido ao seu design de velocidade. Use algo como bcrypt ou possivelmente scrypt e tire o problema de suas mãos completamente.

Ah, e nem sequer pensar em comparar os hashes resultantes para a igualdade com a sua linguagem de programação ou utilitários de comparação de seqüência de database. Aqueles comparam o caractere por caractere e o curto-circuito como false se um caractere diferir. Portanto, agora os invasores podem usar methods estatísticos para tentar descobrir o que é o hash, um caractere por vez.

Não deveria fazer nenhuma diferença. O hash não será mais fácil de adivinhar onde quer que você coloque o sal. As colisões de hash são raras e imprevisíveis, em virtude de serem intencionalmente não lineares. Se isso fizesse diferença na segurança, isso sugeriria um problema com o hashing, não com a salga.

Se estiver usando um hash criptograficamente seguro, não importa se você pré ou pós-correção; Um ponto de hashing é que uma única mudança de bit nos dados de origem (não importa onde) deve produzir um hash diferente.

O que é importante, porém, é usar sais longos, gerando-os com um PRNG criptográfico adequado e tendo sais por usuário. Armazenar os sais por usuário em seu database não é um problema de segurança, usando um hash em todo o site.

Primeiro de tudo, o termo “mesa de arco-íris” é consistentemente mal utilizado. Uma tabela “arco-íris” é apenas um tipo específico de tabela de consulta, que permite um tipo específico de compactação de dados nas chaves. Ao negociar computação para espaço, uma tabela de consulta que levaria 1.000 TB pode ser compactada milhares de vezes para que possa ser armazenada em uma unidade de disco menor.

Você deve estar preocupado com o hash para tabelas de consulta de senha, arco-íris ou não.

@ onebyone.livejournal.com:

O atacante tem ‘tabelas de arco-íris’ consistindo não dos hashes das palavras do dictionary, mas do estado do cálculo de hash antes de finalizar o cálculo de hash.

Pode então ser mais barato forçar brutalmente uma input de arquivo de senha com sal postfix do que prefixo salt: para cada palavra do dictionary, você carregaria o estado, adicionaria os salt bytes no hash e, em seguida, o finalizaria. Com o sal prefixado, não haveria nada em comum entre os cálculos para cada palavra do dictionary.

Para uma function hash simples que varre linearmente a string de input, como um simples gerador congruente linear, esse é um ataque prático. Mas uma function hash criptograficamente segura é deliberadamente projetada para ter múltiplas rodadas, cada uma das quais usa todos os bits da string de input, de forma que calcular o estado interno imediatamente antes da adição do sal não é significativo após a primeira rodada. Por exemplo, o SHA-1 tem 80 rodadas.

Além disso, algoritmos de hashing de senha como o PBKDF compõem sua function hash várias vezes (recomenda-se iterar PBKDF-2 no mínimo 1.000 vezes, cada iteração aplicando SHA-1 duas vezes) tornando esse ataque duplamente impraticável.

Array BCrypt se a plataforma tiver um provedor. Eu amo como você não se preocupa em criar os sais e pode torná-los ainda mais fortes, se quiser.

Inserir o salt um número arbitrário de caracteres na senha é o caso menos esperado e, portanto, o mais “seguro” socialmente, mas não é muito significativo no caso geral, desde que você esteja usando uma senha longa e exclusiva por senha. cordas para sais.