O SHA-1 é seguro para armazenamento de senhas?

148

Conclusão: O SHA-1 é tão seguro quanto qualquer coisa contra ataques de pré-imagem, no entanto, é fácil calcular, o que significa que é mais fácil montar um ataque de força bruta ou de dicionário. (O mesmo vale para sucessores como o SHA-256.) Dependendo das circunstâncias, uma função de hash projetada para ser computacionalmente cara (como o bcrypt) pode ser uma escolha melhor.


Algumas pessoas fazem comentários como "SHA-1 está quebrado" muito, então estou tentando entender o que exatamente isso significa. Vamos supor que eu tenho um banco de dados de hashes de senha SHA-1 e um invasor com um algoritmo de quebra de SHA-1 de ponta e um botnet com 100.000 máquinas obtém acesso a ele. (Ter controle sobre 100 mil computadores domésticos significa que eles podem realizar cerca de 10 ^ 15 operações por segundo.) Quanto tempo eles precisariam

  1. descobrir a senha de qualquer usuário?
  2. descobrir a senha de um determinado usuário?
  3. descobrir a senha de todos os usuários?
  4. encontrou uma maneira de fazer login como um dos usuários?
  5. encontrou uma maneira de fazer login como um usuário específico?

Como isso muda se as senhas forem salgadas? O método de salgar (prefixo, postfix, ambos ou algo mais complicado como xor-ing) é importante?

Aqui está o meu entendimento atual, depois de pesquisar no Google. Corrija as respostas se eu entendi algo errado.

  • Se não houver sal, um ataque do arco-íris encontrará imediatamente todas as senhas (exceto as extremamente longas).
  • Se houver um sal aleatório suficientemente longo, a maneira mais eficaz de descobrir as senhas é uma força bruta ou ataque de dicionário. Os ataques de colisão e de pré-imagem não ajudam em nada a descobrir a senha real; portanto, os ataques criptográficos contra o SHA-1 não ajudam aqui. Não importa muito qual algoritmo é usado - é possível usar o MD5 ou o MD4 e as senhas seriam igualmente seguras (há uma pequena diferença porque o cálculo de um hash SHA-1 é mais lento).
  • Para avaliar o quão seguro é "tão seguro", vamos supor que uma única execução do sha1 execute 1000 operações e as senhas contenham maiúsculas, minúsculas e dígitos (ou seja, 60 caracteres). Isso significa que o invasor pode testar 10 15 * 60 * 60 * 24/1000 ~ = 10 17 possíveis senhas por dia. Para um ataque de força bruta, isso significaria testar todas as senhas com até 9 caracteres em 3 horas, até 10 caracteres em uma semana e até 11 caracteres em um ano. (Leva 60 vezes mais para cada caractere adicional.) Um ataque de dicionário é muito, muito mais rápido (mesmo um invasor com um único computador pode executá-lo em horas), mas só encontra senhas fracas.
  • Para efetuar login como usuário, o invasor não precisa descobrir a senha exata; basta encontrar uma sequência que resulte no mesmo hash. Isso é chamado de primeiro ataque de pré-imagem. Tanto quanto pude encontrar, não há ataques de pré-imagem contra o SHA-1. (Um ataque de força bruta levaria 2 160 operações, o que significa que nosso atacante teórico precisaria de 10 a 30 anos para executá-lo. Os limites de possibilidade teórica são de cerca de 2 60 operações, nas quais o ataque levaria alguns anos.) Existem ataques de pré-imagem contra versões reduzidas do SHA-1 com efeito desprezível (para o SHA-1 reduzido que usa 44 etapas em vez de 80, o tempo de ataque diminuiu de 2 160 operações para 2 157) Existem ataques de colisão contra o SHA-1 que estão bem dentro das possibilidades teóricas ( o melhor que encontrei reduz o tempo de 2 80 para 2 52 ), mas esses são inúteis contra hashes de senhas, mesmo sem salga.

Em resumo, o armazenamento de senhas com o SHA-1 parece perfeitamente seguro. Perdi alguma coisa?

Atualização: Marcelo apontou um artigo que menciona um segundo ataque de pré-imagem em 2 106 operações . ( Editar: Como Thomas explica , este ataque é uma construção hipotética que não se aplica a cenários da vida real.) Ainda não vejo como isso significa perigo para o uso do SHA-1 como uma função de derivação chave. Geralmente, existem boas razões para pensar que um ataque de colisão ou um segundo ataque de pré-imagem pode eventualmente se transformar em um primeiro ataque de pré-imagem?

Tgr
fonte
Agora ele tem 7 anos e muita coisa aconteceu desde a última edição. SHA-1 não é mais considerado suficientemente seguro para hash de senha
GordonM
@GordonM o que aconteceu? Com o aumento do poder da computação, os ataques de colisão SHA-1 estão se tornando cada vez mais práticos, mas não são realmente relevantes aqui. O SHA-1 nunca foi realmente seguro para o hash de senha (os hashes rápidos geralmente não são), mas, na medida em que era, ainda é o AFAIK.
Tgr
SHA-1 nunca foi seguro para hash de senha porque nunca foi intenção para proteger senhas em primeiro lugar ...
Azxdreuwa

Respostas:

209

A resposta curta para sua pergunta é: SHA-1 é o mais seguro possível. MD5 também seria bom, até MD4; mas isso pode deixar alguns investidores nervosos. Para relações públicas , é melhor usar uma função hash "melhor", por exemplo, SHA-256, mesmo se você truncar sua saída para 160 ou 128 bits (para economizar no custo de armazenamento). Alguns dos candidatos da segunda rodada do SHA-3 parecem ser mais rápidos que o SHA-1, embora sejam indiscutivelmente "mais seguros"; No entanto, eles ainda são um pouco novos, portanto, seguir o SHA-256 ou o SHA-512 seria uma rota mais segura no momento. Isso faria você parecer profissional e cauteloso, o que é bom.

Observe que "o mais seguro possível" não é o mesmo que "perfeitamente seguro". Veja abaixo explicações bastante longas.

Sobre ataques conhecidos:

Os ataques conhecidos no MD4, MD5 e SHA-1 são sobre colisões, que não afetam a resistência à pré-imagem. Foi demonstrado que o MD4 possui alguns pontos fracos que podem ser explorados (apenas teoricamente) ao tentar quebrar o HMAC / MD4, mas isso não se aplica ao seu problema. O ataque de pré-imagem de 2 106 segundos no artigo de Kesley e Schneier é uma troca genérica que se aplica apenas a entradas muito longas (2 60 bytes; isso é um milhão de terabytes - observe como 106 + 60 excede 160; é aí que você vê que o trade-off não tem nada de mágico).

O restante desta mensagem assume que a função de hash usada (por exemplo, SHA-1) é uma "caixa preta" sem nenhuma propriedade especial que o invasor possa usar. É isso que você tem agora mesmo com as funções hash "quebradas" MD5 e SHA-1.

Sobre tabelas arco-íris:

O "ataque do arco-íris" é na verdade o compartilhamento de custos de um dicionário ou ataque de força bruta. É um derivado da troca de memória de tempo descrita pela primeira vez por Hellman em 1980. Supondo que você tenha N possíveis senhas (esse é o tamanho do seu dicionário ou 2 n se você considerar forçar brutalmente uma função hash com uma saída de n bits), há um ataque de compartilhamento de tempo no qual você pré-calcula as senhas com hash N e as armazena em uma grande tabela. Se você classificar as saídas de hash, poderá obter sua senha em uma única pesquisa. Uma mesa arco-íris é uma maneira inteligente de armazenar essa mesa com um espaço muito reduzido. Você armazena apenas senhas com hash N / t e as quebra com O (t 2 ) pesquisas. As tabelas Rainbow permitem que você lide virtualmente com tabelas pré-computadas muito maiores do que as que você pode armazenar realisticamente.

No entanto, arco-íris ou não, o atacante ainda precisa executar o ataque completo pelo menos uma vez. Isso pode ser visto como várias camadas sucessivas de otimização:

  1. O ataque de força bruta / dicionário custou N por quebrar cada senha.
  2. Com uma tabela pré-computados, o atacante paga esse custo N uma vez e pode, posteriormente, atacar muitas senhas com custo muito pequeno extra por senha.
  3. Se a tabela pré-calculada for uma tabela arco-íris, N pode ser um pouco maior, porque o custo de armazenamento é reduzido. O gargalo em N se torna a potência da CPU que o invasor pode reunir, não o tamanho de seus discos rígidos.

Se N for grande o suficiente para que o custo da CPU de hash N de senhas seja ridículo, esse ataque não será possível, independentemente de as tabelas arco-íris serem usadas ou não. Isso significa que uma função de hash (resistente à pré-imagem) com uma saída de 80 bits ou mais é suficiente para tornar inviável o ataque de força bruta.

Sobre sais:

Os sais são uma maneira de derrotar os pré-cálculos. Na descrição acima, o salt retorna ao invasor para a etapa 1: salgar impede que o invasor compartilhe o custo de O ( N ) entre várias senhas atacadas. As tabelas pré-calculadas, a fortiori tabelas arco-íris, não são mais viáveis.

Você quer salgar porque, quando os dados do hash consistem em senhas , ou seja, algo que se encaixa no cérebro de um ser humano aleatório, N pode ser bem baixo: os humanos são realmente ruins em escolher e lembrar senhas. É disso que se trata "ataques de dicionário": usar um espaço reduzido de senhas em potencial (o "dicionário") sob a suposição de que muitas senhas de usuários estarão nesse espaço especialmente selecionado.

Portanto, a salga impedirá pelo menos o invasor de usar tabelas pré-calculadas, em particular tabelas arco-íris pré-calculadas. Isso pressupõe que o atacante será capaz de quebrar uma senha ou dois; não queremos que ele quebre 1000 outras senhas com pouca sobrecarga extra.

Além disso, salga é bom para relações públicas.

Sobre o custo SHA-1:

O custo elementar do SHA-1 é sobre o hash de um bloco de 64 bytes. É assim que o SHA-1 funciona: os dados são preenchidos e depois divididos em blocos de 64 bytes. O custo do processamento de um único bloco é de cerca de 500 ciclos de clock em um sistema Intel Core2, e isso é para um único núcleo. MD5 e MD4 são mais rápidos, contam cerca de 400 e 250 ciclos, respectivamente. Não esqueça que a CPU mais moderna possui vários núcleos, portanto, multiplique de acordo.

Alguns esquemas de salga prescrevem enormes sais; por exemplo, o que entra na função hash é, na verdade, 40000 cópias sucessivas de um único salt de 128 bits, seguido pela própria senha. Isso torna o hash da senha mais caro (por um fator de 10.000 no meu exemplo), tanto para o usuário legítimo quanto para o invasor. Se é uma boa ideia, depende da configuração. Para o login em um sistema desktop, isso é bom: o usuário nem notará que foram necessários 10ms para colocar sua senha em hash, em vez de 1µs; mas o custo para o invasor aumentou um fator muito notável de 10000. Em servidores compartilhados com milhares de clientes por segundo, o custo agregado pode se tornar proibitivo. Conceitualmente, elevar a fasquia pelo mesmo fator para o usuário legítimo e o atacante não é, em última análise, uma boa segurança; mas pode ser uma ideia interessante em algumas situações específicas.

Sobre ataques online:

Tudo acima é sobre como derrotar ataques offline . Um ataque offline é um ataque em que o invasor possui todos os dados necessários para "testar" senhas; por exemplo, o invasor pode obter uma cópia do banco de dados contendo as senhas com hash. Em um ataque offline, o atacante é limitado apenas por seus recursos computacionais. Por outro lado, um ataque on - line é um ataque em que cada palpite do atacante deve passar por um verificador honesto (por exemplo, o atacante simplesmente tenta efetuar login no sistema atacado). Os ataques online são frustrados ao impor limites de quantas senhas podem ser tentadas por segundo. Exemplos extremos são cartões inteligentes que são desativados após três PINs incorretos.

Geralmente, para segurança da senha, compensa muito mais organizar o sistema para não permitir que um invasor crie um ataque offline. É o que os sistemas Unix fazem: as senhas com hash, que costumavam estar no /etc/passwordarquivo legível por todo o mundo , agora estão no /etc/shadowarquivo protegido contra acesso de leitura, exceto por alguns aplicativos privilegiados. A suposição aqui é que, se o invasor puder ler /etc/shadow, ele provavelmente terá controle suficiente sobre o sistema e não precisará mais de senhas ...

Thomas Pornin
fonte
5
Excelente resposta. A única parte com a qual eu discordo é "Conceitualmente, elevar a fasquia pelo mesmo fator para o usuário legítimo e o invasor não é, em última análise, uma boa segurança" - o invasor precisa realizar uma grande variedade de operações que o usuário deve executar. A adição de um ciclo de relógio para um login de usuário adiciona milhões para um invasor.
Nick Johnson
1
@ Thomas Isso permanece preciso e provavelmente continuará sendo preciso por um futuro indefinido e previsível. Os hackers podem adivinhar senhas reais através de qualquer tipo de hash devido à baixa qualidade das senhas comuns. Adivinha "123456" e você sempre terá alguns hits. Isso permanecerá verdadeiro, independentemente do armazenamento de senha que você usar.
tylerl
1
Apenas meu ponto de vista, mas por que você adotaria o SHA1, quando uma criptografia de senha mais forte já está amplamente disponível? Há um ano, o MD5 era considerado "seguro" e agora não é - o mesmo poderia acontecer com o SHA1 a qualquer dia, pelo que sabemos. Pessoalmente, vou apostar no Blowfish a partir deste momento - parece ter um representante melhor e menos especialistas preocupados na comunidade de criptografia, está disponível em quase qualquer lugar, por isso não há razão para jogar com o SHA1.
mindplay.dk
1
Estou chocado ao ver minha resposta de @ThomasPornin dizendo que o MD5 é seguro para armazenamento de senhas. Se o MD5 está bom, por que TUDO diz não usá-lo, use bcrypt? Eles estão sendo cautelosos? Eu li e entendi tudo e fiquei com a impressão de que o MD5 era muito ruim porque muito vulnerável à força bruta. Os comentários de um ano atrás não contradizem a resposta ...
temporary_user_name
1
@ Aerovistae: você pode dar uma olhada nessa resposta no site security.SE; Ele contém mais análises e detalhes recentes sobre o hash da senha.
Thomas Pornin
30

As respostas anteriores não fazem menção às GPUs, que podem paralelizar o hash SHA-1, na medida em que um banco de dados inteiro agora pode ser forçado brutalmente em minutos ou horas, em vez de dias ou semanas, mesmo que as senhas tenham sido salgadas.

Os algoritmos modernos de hash de senha, como bcrypt ou scrypt, são projetados especificamente para serem difíceis de executar em GPUs, devido ao fato de serem cifras de bloco com requisitos de memória muito mais altos (e o acesso à memória em uma GPU não pode ser paralelizado na mesma extensão). Eles também têm uma "função de trabalho" que permite que eles fiquem mais lentos em tempo real à medida que a tecnologia melhora.

Em resumo, você deve usar apenas as melhores ferramentas para o trabalho. E o SHA-1 fica muito aquém do estado da arte.

Para leitura adicional:

jammycakes
fonte
2
"Os algoritmos modernos de hash de senha, como bcrypt ou PBKDF2, foram projetados especificamente para serem difíceis de executar em GPUs" - você quis dizer "bcrypt or scrypt"? O PBKDF2 é apenas um hash iterado, não há nada que seja problemático para uma GPU.
Tgr 8/07/12
4
Por favor, deixe-me saber qual GPU você usa, eu comprarei o mesmo. Se você puder realizar 2 ^ 160 cálculos SHA-1 em "minutos" (isso seria menor que "horas", portanto, no máximo 59 minutos), será necessário executar mais de 10 ^ 44 por segundo. Como o PCIe transfere um limite de 128GT / s, sua GPU também deve ter uma incrível memória interna. Quero isso.
Damon
3
@ Damon: Você parece estar assumindo que os usuários têm senhas "triviais" (<8 bits de entropia) ou senhas "inquebráveis" (> 60 bits de entropia). Você está ignorando completamente todos aqueles cuja entropia de senha está no intervalo de 10 a 60 bits. Esses são os usuários em que bcrypt, tabelas arco-íris e GPUs, e eles compõem tipicamente cerca de 80% de uma base de usuários típica.
jammycakes
1
(opa ... eu deveria ter dito: "Esses são os usuários em que bcrypt, tabelas arco-íris e GPUs fazem a maior diferença") #
jammycakes
3
Para algumas estatísticas e análises, consulte troyhunt.com/2011/06/brief-sony-password-analysis.html - enquanto 36% dos usuários escolhem senhas que aparecem nos dicionários de senhas, apenas 2-3% escolhem as mais comuns.
Jammycakes
7

Sua descrição parece precisa para o estado da arte atual.

Porém, você não deve usar uma única iteração de qualquer função de hash: No mínimo, você deve iterar várias vezes (1000 iterações do hash aumentam o trabalho do atacante em 1000 vezes. Ele aumenta o seu trabalho na mesma quantidade, mas você está fazendo muito menos hash de senha do que eles).

Idealmente, no entanto, você deve usar uma primitiva de armazenamento de senha existente, como as descritas aqui .

Nick Johnson
fonte
Iterar milhares de vezes não é uma idéia tão boa quanto você imagina. Aumenta o risco de uma colisão de hash. yorickpeterse.com/articles/use-bcrypt-fool
jammycakes
1
Esse artigo parece completamente confuso. Uma função de hash seguro não perde entropia apreciável através do hash iterativo, e o hash iterativo é um componente essencial dos principais esquemas de alongamento, como PBKDF2 e scrypt. Até o bcrypt, recomendado pelo autor, usa uma construção semelhante. Seu 'ataque' baseia-se em encontrar uma pré-imagem de um hash - nesse caso, a maioria das construções que usam esse hash são completamente quebradas de qualquer maneira. Por fim, não recomendo que as pessoas usem hashes iterativos diretamente - como digo na minha pergunta, você deve usar um primitivo existente projetado para esse fim.
Nick Johnson
7

SHA1 é um resumo da mensagem , nunca foi concebido para ser uma função de hash de senha (ou derivação de chave). (Embora possa ser usado um componente básico para um KDF, como no PBKDF2 com HMAC-SHA1.)

Uma função de hash de senha deve se defender contra ataques de dicionário e tabelas arco-íris. Vários algoritmos foram projetados para atingir esse objetivo.

Atualmente, a melhor opção é provavelmente o Argon2 . Essa família de funções de hash de senhas venceu a Competição de hash de senhas em 2015.

Se o Argon2 não estiver disponível, a única outra função padronizada de hash de senha ou derivação de chave é PBKDF2 , que é um padrão NIST antigo. Outras opções, se não for necessário usar um padrão, incluem bcrypt e the scrypt .

A Wikipedia possui páginas para estas funções:

Erwan Legrand
fonte
4

Foram descobertas vulnerabilidades graves no SHA-1, que tornam a pesquisa muito mais rápida que a força bruta. Ainda é em grande parte intratável, mas não se espera que isso aconteça por muito mais tempo; programadores paranóicos favorecem algo da família SHA-2.

A partir deste artigo sobre o resultado original 2005:

"É hora de caminhar, mas não correr, até as saídas de incêndio. Você não vê fumaça, mas os alarmes de incêndio dispararam."

Não é que a atual análise criptográfica torne o SHA-1 inseguro, mas a comunidade criptográfica está preocupada com a possibilidade de notícias piores estarem chegando. Esse medo também se aplica ao SHA-2, que apresenta as mesmas falhas do SHA-1, embora em um espaço de pesquisa muito maior, daí a busca contínua pelo SHA-3 .

Em resumo, o SHA-1 está seguro no momento e provavelmente chegará por algum tempo, mas a comunidade de criptografia não se sente à vontade com o prognóstico.

Marcelo Cantos
fonte
Você poderia fornecer um link? Como eu disse, o melhor ataque de pré-imagem que encontrei torna a pesquisa 8 vezes mais rápida e, mesmo para isso funcionar, você precisa omitir metade das etapas do SHA-1. (Além disso, eu acho que é um segundo ataque preimage, que é inútil contra os hashes de senha.)
Tgr
Eu também sou cético em relação a algo que vem da NSA, à luz da recente notícia :)
Alex W
4

A partir de fevereiro de 2017, o SHA-1 não deveria mais ser considerado seguro. O Google relatou sucesso com ataques de colisão contra o SHA-1 completo e sem redução ( link para o relatório ). Para o anúncio do Google, clique aqui .

Edit: Como apontado por outros, as senhas não são vulneráveis ​​a ataques de colisão de hash. No entanto, como orientação geral, eu não escolheria o SHA-1 para aplicativos relacionados à segurança. Existem melhores alternativas por aí.

Aaron
fonte
OK, encontrar uma colisão SHA-1 levou aproximadamente 6.500 anos de CPU e 100 anos de GPU , não é um ataque de produção. Quebrar uma senha não é uma força bruta contra todas as entradas possíveis, mas contra listas de 10.000.000 de senhas frequentes. Aqui está o jornal .
Zaph
1
A falha está usando apenas qualquer função de hash para proteger senhas. O simples uso de uma função hash não é suficiente e apenas adicionar um sal faz pouco para melhorar a segurança, os hashes criptográficos são muito rápidos. Em vez disso, itere sobre um HMAC com um sal aleatório por cerca de 100 ms e salve o sal com o hash. Use funções como PBKDF2(aka Rfc2898DeriveBytes), password_hash/ password_verify, Bcrypte funções similares. O objetivo é fazer com que o invasor gaste muito tempo encontrando senhas com força bruta. É importante proteger seus usuários, use métodos de senha seguros.
Zaph
Colisão não é pré-imagem e senhas não são assinaturas. Os ataques de colisão não funcionam com senhas porque exigem conhecimento do texto sem formatação original.
Tgr
Tgr: concordou, obrigado. Zaph: Sim, salgar para proteger contra ataques do arco-íris e usar hashes criptográficos lentos estão entre as práticas recomendadas que eu não lidei especificamente nesta resposta.
Aaron
3

Se você armazenar a senha salgada, o SHA-1 será bom para propósitos práticos. O SHA-2 é considerado mais seguro, mas o SHA-1 não é um problema, a menos que você tenha um motivo para ser verdadeiramente paranóico.

Aqui está o que o NIST diz :

Os resultados apresentados até agora no SHA-1 não questionam sua segurança. No entanto, devido aos avanços da tecnologia, o NIST planeja eliminar o SHA-1 em favor das funções de hash maiores e mais fortes (SHA-224, SHA-256, SHA-384 e SHA-512) até 2010.

VladV
fonte
Isso é um comentário NIST partir de 2004. O projecto de recomendação 2010 diz SHA-1 é aprovado para todas as aplicações de geração de assinatura não-digitais para além de 2010.
Tgr