Sobre o armazenamento de senhas no banco de dados



Hoje veremos a melhor forma de armazenar senhas em um banco de dados e como plataformas conhecidas resolvem esse problema.

Texto simples


Quando surgiu a questão de armazenar senhas, é claro, a primeira idéia foi simplesmente escrevê-las abertas na placa de identificação apropriada no banco de dados. E tudo ficaria bem se os clientes não pudessem realmente acessar diretamente. Infelizmente, porém, essa injeção SQL bem conhecida às vezes ainda funciona em vários aplicativos da web, sem mencionar outras vulnerabilidades em potencial. Em questões de segurança, geralmente é aceito assumir o pior e preparar um plano de ação e proteção, mesmo nesse caso. Assumimos que um invasor encontrou uma brecha em um aplicativo da Web, de uma maneira ou de outra, descarrega alegremente uma tabela com nomes de usuário e senhas e, em seguida, as descarta como bem entender. Em geral, suas ações adicionais podem ser as seguintes:

  • executando ações ilegítimas em nome de usuários usando suas credenciais em um recurso vulnerável: por exemplo, um cartão bancário está vinculado a uma conta e agora um invasor pode usá-lo;
  • uma tentativa de usar a senha recebida em outros recursos: longe de sempre, os usuários, seguindo os conselhos, criam novas senhas para diferentes serviços a cada vez;
  • uma tentativa de identificar a regra para gerar uma senha e ir para o segundo ponto: alguns formam uma regra para gerar uma senha; como resultado, as senhas em diferentes recursos são diferentes, mas obedecem à mesma regra que pode ser detectada;
  • escalonamento de privilégios: a senha do administrador também pode ser armazenada na mesma tabela, com o conhecimento do qual às vezes você pode obter controle total sobre o servidor.

Hashing de criptografia


A idéia imediatamente acaba não sendo tão boa. O que fazer Seria ótimo armazenar senhas na forma criptografada. Então, mesmo que sejam removidos, eles não poderão se recuperar ou, pelo menos, passarão muito tempo com isso. Aqui, a escolha surge entre dois ramos do desenvolvimento: criptografar senhas ou hash. Os desenvolvedores se estabeleceram no segundo e, em princípio, é claro o porquê. Compare nossos candidatos para diferentes características:

  1. Entrada de trabalho. A criptografia leva mais tempo e, independentemente da conversão que escolhermos, será necessário realizar todas as verificações de senha. Um dos requisitos para as funções de hash é a velocidade de execução.
  2. O comprimento dos valores de saída. O resultado da criptografia é variável em tamanho, o resultado do hash é sempre o mesmo e armazenar dados uniformes em um banco de dados é muito conveniente. Sem mencionar o fato de que o tamanho da senha na forma criptografada fornecerá algumas informações sobre o tamanho da senha original. O mesmo comprimento, no entanto, leva à possibilidade de colisões, mas mais sobre isso abaixo.
  3. Gerenciamento de chaves. A criptografia requer uma chave, que também precisará ser armazenada em algum lugar e espero que ninguém a encontre. De qualquer forma, a geração e o gerenciamento de chaves são uma história separada (eles não devem ser fracos, precisam ser alterados regularmente e assim por diante).
  4. A possibilidade de conflito. Ao criptografar, a saída de diferentes dados de entrada também será sempre diferente. Com o hash, esse nem sempre é o caso. Um comprimento de hash constante significa que o conjunto de valores de saída da função de hash é limitado, o que leva à colisão. Ou seja, digamos que o usuário realmente ficou confuso e criou uma senha longa muito legal, que possui caracteres especiais, números e letras em maiúsculas e minúsculas. O invasor insere a senha não menos legal "admin" no campo de senha. O servidor fez o hash para verificação e comparação de hashes. Hashes combinados. É uma pena.

Assim, com uma pontuação de 3: 1, o hash vence. Mas é possível parar por aí?
A resposta é não.

Ataques com senha com hash


Então, o atacante conseguiu nossa mesa com nomes de usuário e senhas. As senhas agora estão com hash, mas isso não impede o invasor e ele pretende seriamente recuperá-las. Suas possíveis ações:

  • força bruta do dicionário: se o invasor não obteve êxito com a senha de referência do administrador, ele se volta para o dicionário de senhas populares e tenta a sorte com seus hashes;
  • tabelas do arco-íris: hoje em geral, talvez ele não precise calcular nada e classificar o dicionário. Será suficiente recorrer às tabelas do arco-íris na rede. As tabelas Rainbow contêm valores de hash já calculados por alguém antes e seus dados de entrada correspondentes. É importante observar que, devido a colisões, a senha que a tabela rainbow oferecerá não será necessariamente a que o usuário usa. Os valores calculados já são para MD5, SHA1, SHA256, SHA512, bem como para suas modificações e algumas outras. Você pode tentar reverter o hash, por exemplo, aqui ;
  • pesquisa exaustiva: se isso não ajudar, você terá que recorrer à força bruta e repetir todas as senhas possíveis seguidas até que os hashes calculados finalmente correspondam.

No caso mais geral, um invasor precisará decifrar senhas. E aqui seu sucesso dependerá, entre outras coisas, da velocidade de computação da função hash. Uma comparação do tempo dos hashes pode ser encontrada aqui . Por exemplo, as funções de hash implementadas em Java no Windows 10 de 64 bits com 1 núcleo Intel i7 de 2,60 GHz e 16 GB de RAM foram executadas um milhão de vezes para calcular um hash de 36 caracteres. Eles mostraram os seguintes resultados:

MD5 - 627 ms
SHA-1 - 604 ms
SHA-256 - 739 ms
SHA-512 - 1056 ms

Hoje, porém, o bruteforce pode ser paralelo e funcionar muitas vezes mais rápido na GPU (assim como na APU, DSP e FPGA). No entanto, além de escolher um algoritmo mais longo e uma saída mais longa, você pode fazer outra coisa.

Hash hash


Para impedir que um invasor use tabelas arco-íris prontas, existe uma técnica para hash uma senha várias vezes. Ou seja, calculamos o hash do hash do hash do hash ... e, portanto, n vezes (é necessário, no entanto, não nos envolvermos demais com isso, porque o servidor também precisará fazer isso durante a verificação regular da senha do usuário). Agora, é tão simples, de acordo com a tabela do arco-íris, que ele não encontrará a senha e o tempo para a força bruta aumentará significativamente. Mas nada impede o invasor de gerar uma tabela arco-íris a partir do dicionário de senhas, conhecendo o algoritmo de hash. Além disso, para as combinações mais populares desse método, essas tabelas já foram geradas:

"

Adicione sal a gosto


Para que ele não pudesse fazer isso, as senhas são hash hoje com a adição de sal.
Um salt é uma sequência aleatória extra atribuída a uma senha e com hash. Você não pode recuperar a senha do hash obtido da tabela arco-íris. Conhecendo o sal e o hash de saída, o atacante está fadado à força bruta e nenhuma tabela pré-calculada provavelmente o ajudará.
Taxonomia de salga de senha:

1. De acordo com o princípio da salga:

  • um sal único para cada usuário: individual para cada usuário - dessa maneira, se o sal se tornar conhecido pelo invasor, cada senha deverá ser alterada. Além disso, mesmo que dois usuários pensem da mesma maneira e criem senhas idênticas, os hashes ainda serão diferentes na saída;
  • sal global: o mesmo para todos, usado para todos os hashes;
  • isso e outro.

2. De acordo com o método de armazenamento de sal:

  • no banco de dados: como regra, sais individuais são armazenados no mesmo banco de dados que os hashes de senha; frequentemente até na mesma linha;
  • no código (leia-se: na configuração): o salt global geralmente é armazenado não no banco de dados, mas, por exemplo, na configuração, para que o violador tenha que gastar tempo na sua seleção.

Assumimos que os sais de usuários individuais sejam armazenados no banco de dados, o sal global na configuração. O atacante obteve acesso ao banco de dados e conhece todos os hashes e seus sais correspondentes (o sal global não é armazenado no banco de dados e ele não o conhece). No total, se todos os métodos forem combinados, a fim de obter senhas de forma clara, como foi o caso nos primeiros sistemas, ele, sendo extremamente proposital, encontrará os seguintes obstáculos:

  1. Ele não conhece o sal global, então terá que ser brutalizado.
  2. Ele conhece os sais dos usuários, mas não possui tabelas preparadas com esses sais, portanto terá que decifrar senhas.
  3. Esse processo levará ainda mais tempo devido ao fato de você precisar fazer hash hash n vezes.

Como as senhas armazenam vários CMS


Wordpress


Antes da versão 3.x, as senhas eram simplesmente hash com MD5. Agora a biblioteca phpass é usada. Por padrão, salt é atribuído à senha à frente e a sequência resultante é hash MD5 2 ^ 8 vezes.

Joomla


Antes da versão 1.0.12, apenas o MD5 era usado. A biblioteca phpass é usada, por padrão, bcrypt com salt e 2 ^ 10 repetições.

Drupal


Até a versão 6 md5 sem sal. A biblioteca phpass é usada. O padrão é sha512 salgado com 2 ^ 16 repetições.

Silverstripe


Usa Blowfish salgado com 2 ^ 10 repetições.

Umbraco


Usa HMACSHA256 com sal. Usa o segundo sal global especificado na configuração.

Source: https://habr.com/ru/post/pt413157/


All Articles