Salgando sua senha: práticas recomendadas?

162

Eu sempre fiquei curioso ... O que é melhor ao salgar uma senha para hash: prefixo ou postfix? Por quê? Ou importa, desde que você salgue?

Para explicar: Todos nós (esperamos) sabemos até agora que devemos salgar uma senha antes de usá-la para armazená-la no banco de dados [ Editar: Para que você possa evitar coisas como o que aconteceu com Jeff Atwood recentemente ]. Normalmente, isso é feito concatenando o salt com a senha antes de passá-la 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 diminua a chance de uma colisão de hash? Meu Google não encontrou uma análise decente sobre o assunto.

Edit: Ótimas respostas pessoal! Me desculpe, eu só poderia escolher uma resposta. :)

Randolpho
fonte
1
@ Jaccco: entrada incrível. Obrigado!
Randolpho
3
A melhor prática é usar uma função criptográfica que faça a salga para você, usando PBKDF2 (o padrão), bcrypt ou mesmo scrypt. Obrigado a Stephen por apontar isso.
Maarten Bodewes
1
Praticamente todas as construções de hash de senha padrão cuidam da combinação de salt e senha, portanto você não deve se preocupar com isso. Se você não usar um hash de senha padrão, migre para um.
CodesInChaos
1
@Omu Recomendação ruim. 1) Uma única iteração do SHA-1 é muito rápida, você deve usar pelo menos 10000 e até isso é bastante fraco. 2) O sal padrão é muito pequeno. 8 bytes é mínimo e 16 é recomendado.
CodesInChaos

Respostas:

111

Prefixo ou sufixo é irrelevante, trata-se apenas de adicionar alguma entropia e comprimento à senha.

Você deve considerar essas três coisas:

  1. O sal deve ser diferente para cada senha que você armazena. (Esse é um mal-entendido bastante comum.)
  2. Use um gerador de números aleatórios criptograficamente seguro.
  3. Escolha um sal por tempo suficiente. Pense no problema do aniversário.

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

Georg Schölly
fonte
4
Eu adicionei um link para uma pergunta antiga, leia essas respostas. Basicamente, ao não usar um sal aleatório diferente por senha, você corre um risco desnecessário à segurança, que pode ser um problema real no futuro.
Georg Schölly 23/03/09
39
O sal aleatório em todo o site é ruim, pois um invasor pode precomputar tabelas arco-íris e pegar todo o banco de dados do usuário. Se você não entender isso, não escreva sistemas de login / segurança :) - você PRECISA de sais por usuário.
Snemarch 23/03/09
3
Sim, sal por usuário. Idealmente, com iterações por usuário armazenadas (para que você possa aumentar o número de iterações usadas ao longo do tempo). Qualquer estrutura decente terá esse recurso embutido. (NET tem PasswordDeriveBytes que vai cuidar de tudo para você.)
MichaelGG
2
Se você estiver projetando qualquer tipo de sistema de segurança, é recomendável não usar sal por usuário. seu site pode não ser super-interessante, mas considere os usuários usando a mesma senha em vários sites ... tentando manter o banco de dados seguro tende a falhar :)
snemarch
2
É claro que os sais protegem contra ataques de dicionário, precisamente tornando-os muito mais lentos. O uso de sais nas senhas é muito anterior às tabelas do arco-íris. Os sais foram adicionados especificamente para retardar os ataques do dicionário, impedindo que os atacantes usem uma senha uma vez e depois a comparem com todos os usuários.
Glenn Maynard
27

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á deve derrotar as tabelas do arco-íris.

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

Seria melhor supor que eles têm a capacidade de armazenar essas tabelas arco-íris, mas não, digamos, tabelas com sais estranhos intercaladas no meio da senha. Em que caso estreito, eu conjecturar que intercaladas 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: © ¤¡

Tom Ritter
fonte
@onebyone, caramba! Ele descobriu o meu sal de 'passwordsalt'!
Samuel
6
@ Samuel: Eu não sei sobre vocês, mas usamos '12345' para o nosso sal. :)
Randolpho
@onebyone válido. Eu realmente quis dizer "comum" como "todos os sais com comprimento X no conjunto de caracteres Y" onde X, Y são razoáveis; digamos 20 caracteres e maiúsculas / minúsculas alfanuméricas. Extensível a dizer todas as strings hexadecimais sob comprimento Z (digamos 160) desde que eu acho que uma mesa de arco-íris de hashes hash seria útil ..
Tom Ritter
1
@Randolpho: Ei, esse também é o meu sal! Quais são as chances?
233 Adrien
E certifique-se o sal não é previsível / Random: stackoverflow.com/questions/1645161/...
Jacco
18

A resposta real, que ninguém parece ter abordado, é que ambos estão errados . Se você estiver implementando sua própria criptografia, por mais trivial que você pense que está fazendo, você cometerá erros.

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

Ah, e nem pense em comparar os hashes resultantes para a igualdade com a linguagem de programação ou os utilitários de comparação de cadeias de banco de dados. Eles comparam caractere por caractere e curto-circuito como falsese um caractere fosse diferente. Portanto, agora os atacantes podem usar métodos estatísticos para tentar descobrir qual é o hash, um personagem de cada vez.

Stephen Touset
fonte
1
Em relação ao último parágrafo: como o atacante conseguiu obter informações sobre o número exato de caracteres em que a comparação falhou? Isso não faz sentido ..
halloweenlv
1
Você está correto e incorreto. Os ataques de tempo são reais e têm sido repetidamente demonstrados viáveis ​​com uma precisão assustadora, mesmo em conexões de rede de latência variável, para determinar exatamente onde a comparação falhou. Dito isso, os ataques de tempo não são realmente aplicáveis ​​aos hashes de senha comuns, pois é inviável computacionalmente encontrar entradas que alteram apenas pequenas partes da saída.
precisa saber é o seguinte
9

Não deve fazer 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, por serem intencionalmente não lineares. Se isso fizesse diferença na segurança, isso sugeriria um problema com o hash, não com a salga.

Phil H
fonte
1
As colisões de hash dependem do tamanho do hash. Graças ao problema do aniversário, as colisões são bastante prováveis.
Georg Schölly 24/03/09
2
Somente se você truncar o resultado. De qualquer forma, continuo afirmando que não fará diferença onde está o sal, porque o objetivo do hash é fazer com que o relacionamento entre entrada e saída não contenha padrões.
24511 Phil H
7

Se estiver usando um hash criptograficamente seguro, não importa se você pré ou pós-fixa; um ponto de hash é que uma única alteração nos dados de origem (não importa onde) produza um hash diferente.

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

snemarch
fonte
2
Resposta incorreta: um invasor pode pré-calcular o MD (passe) para muitas senhas usadas com freqüência e depois calcular o MD (passe + salt) de forma muito barata porque o resumo da mensagem funciona de maneira incremental, a fim de oferecer suporte ao fluxo.
precisa
5

Primeiro de tudo, o termo "tabela arco-íris" é constantemente usado de maneira incorreta. Uma tabela "arco-íris" é apenas um tipo específico de tabela de pesquisa, que permite um tipo específico de compactação de dados nas chaves. Ao trocar a computação por espaço, uma tabela de pesquisa com 1000 TB pode ser compactada mil vezes, para que possa ser armazenada em uma unidade menor.

Você deve estar preocupado com o hash das tabelas de pesquisa de senhas, arco-íris ou outras.

@ onebyone.livejournal.com:

O invasor possui 'tabelas arco-íris' que consistem não nos hashes das palavras do dicionário, mas no estado do cálculo do hash imediatamente antes de finalizar o cálculo do hash.

Poderia ser mais barato forçar com força bruta uma entrada de arquivo de senha com sal postfix do que com prefix salt: para cada palavra do dicionário, por sua vez, você carregaria o estado, adicionaria os bytes de sal ao hash e finalizá-lo. Com sal prefixado, não haveria nada em comum entre os cálculos para cada palavra do dicionário.

Para uma função hash simples que varre linearmente através da cadeia de entrada, como um gerador congruencial linear simples, este é um ataque prático. Mas uma função hash criptograficamente segura é deliberadamente projetada para ter várias rodadas, cada uma das quais usa todos os bits da cadeia de entrada, de modo que a computação do estado interno imediatamente antes da adição do sal não seja significativa após a primeira rodada. Por exemplo, o SHA-1 tem 80 rodadas.

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

cygil
fonte
Você deve verificar a descrição das rodadas. As rodadas são por bloco, não a mensagem inteira. (Caso contrário, o hash de dados de streaming exigiria rebobinar repetidas vezes.) Mas o uso de iterações evita que o problema mencionado acima seja mencionado.
25909 MichaelGG
4

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

Samuel
fonte
3
Por mais que eu saiba, o BCrypt Hash precisa de salga, como qualquer outro esquema de hash.
Jacco
2

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

jeffcook2150
fonte