Header Ads

Como armazenar adequadamente as senhas: Salting, Hashing e PBKDF2

Shutterstock / Anton Shaparenko

As senhas são informações muito privadas e você não quer ser responsável por uma violação de dados. Você deve tomar as maiores precauções se tiver que manipulá-los em seu aplicativo e hash-os corretamente.

A maioria dos problemas de segurança com senhas ocorrem depois que um invasor obtém acesso ao seu servidor e é capaz de visualizar o banco de dados onde você armazena as senhas. Embora seja definitivamente uma boa ideia bloquear o seu servidor para evitar o acesso não autorizado em primeiro lugar, você ainda deve implementar o controle de danos para o pior cenário.

Em vez disso, use o OAuth, se puder

A melhor maneira de lidar com senhas não é. A menos que você tenha uma necessidade específica de lidar diretamente com as senhas, pode usar o OAuth para que outra pessoa cuide disso para você. Isso também é chamado de login de terceiros, e você provavelmente já o encontrou antes, se alguma vez foi solicitado a fazer login no Google ou no Facebook.

OAuth é mais complicado do que a autenticação por senha, mas mesmo se você estiver completamente comprometido, não haverá dados de senha para um invasor ver, nem mesmo hashes.

Nunca armazene senhas em texto simples

Se você tiver que armazenar senhas, nunca deve armazená-las em texto simples em seu servidor. “ Texto simples ” significa que pode ser lido por um invasor com acesso ao seu disco. Por exemplo, se você simplesmente pegar a senha de um usuário e armazená-la em seu banco de dados MySQL, isso será armazenado em texto simples. É por isso que você sempre recebe um link para redefinir sua senha, em vez de a empresa apenas dizer qual era sua senha antiga.

A solução para o problema do texto simples é o hash. Um hash é uma função que assume um valor e gera uma chave exclusiva. Por exemplo, a frase “ senha ” tem um hash SHA256 de:

 6B3A55E0261B0304143F805A24924D0C1C44524821305F31D9277843B8A10F4E 

Mas mudar até mesmo um único dígito (passwerd) muda a saída completamente:

 0B503AEB841F18131DFA86FA052CEF91D9F4D81D301B89F6D035AF89C2CD8AA5 

Portanto, em vez de armazenar a senha no servidor, você armazena este hash. Hashes são diferentes da criptografia porque são funções unilaterais. Você pode fazer o hash de algo, mas é impossível “ remover o hash ” sem apenas forçar brutalmente o hash. Isso significa que não há chave secreta para armazenar e, mesmo se um invasor colocar as mãos em um hash, ele terá que fazer força bruta para ver o conteúdo.

Esta regra de texto simples se aplica a coisas auxiliares como arquivos de log também — se o invasor puder lê-lo de qualquer lugar, isso é um grande problema. Isso também se aplica a métodos de transmissão de texto simples como HTTP, embora você nunca deva enviar senhas pela rede. Você deseja gerar um hash no lado do cliente quando eles o inserirem, para evitar que as senhas sejam detectadas na rede.

Mesmo que proteger o tráfego com HTTPS evite ataques man-in-the-middle no lado do cliente, se um invasor tivesse acesso ao seu servidor, ele poderia descriptografar e farejar as senhas recém-criadas. Isso também torna seu serviço mais confiável, já que o usuário não saberá se você está armazenando secretamente a senha dele nos bastidores. Mas se você vir apenas um hash, mesmo o servidor não sabe qual é a senha.

Se você deseja apenas um bom hash para usar, escolha PBKDF2, pois ele é usado especificamente para armazenar senhas e é muito seguro. Provavelmente, você desejará usar a implementação de JavaScript no lado do cliente, mas se precisar usá-la no lado do servidor, você desejará usar uma implementação para a sua linguagem.

Salve suas senhas

O hash tem um problema, e os hashes de senha normais podem ser quebrados com um método conhecido como rainbow tables.

Para atacar um hash, você pode simplesmente tentar todas as senhas possíveis para cada entrada de hash em seu banco de dados, o que é conhecido como força bruta — lento, mas não totalmente impossível, dependendo de quão fraca é a senha e o hash usado para armazená-lo. Pode levar alguns dias ou semanas de tempo de computação, mas uma senha individual fraca pode ser quebrada eventualmente.

As tabelas Rainbow aceleram isso dramaticamente. Em vez de aplicar força bruta a cada senha individualmente, os hashes para cada senha possível são calculados de antemão e armazenados em um arquivo. Este arquivo pode ser enorme, na escala de muitas centenas de terabytes. Tudo isso é um par de valores-chave de cada senha possível (até um certo tamanho, dependendo da tabela) e o hash correspondente.

É uma troca de espaço de armazenamento por tempo; você só precisa executar o hash uma vez e, em seguida, pode procurá-lo na tabela (o que é muito mais rápido). Essas tabelas estão disponíveis publicamente e são fáceis de gerar.

Para evitar esse vetor de ataque, você deve adicionar um salt — uma string aleatória que você anexa ao final da senha antes de fazer o hash. Em vez de hash de “ senha “, você faria hash:

 senha + 1D75BCA3 ... 

Este salt é armazenado junto com o hash da senha no banco de dados. Quando um usuário insere sua senha, você envia o salt de volta ao usuário para que ele possa adicioná-lo ao hash. Você pode pensar nisso como se cada usuário tivesse sua própria tabela de arco-íris exclusiva, o que vai contra o propósito deles totalmente.

O sal em si não é segredo. Não tem que ser, pois tudo o que está fazendo é impedir a criação da tabela do arco-íris e você está armazenando-a em texto simples de qualquer maneira. As senhas com sal ainda podem ser submetidas a força bruta individualmente.

Na prática, os tamanhos de hash de 32 bytes são bastante comuns, já que hashes realmente curtos ainda são vulneráveis ​​a tabelas de arco-íris. E não reutilize sais; você deve gerar uma nova string aleatória a cada vez.

Use um hash seguro para senhas

Embora SHA256 seja um hash seguro, ele também foi projetado para ser um hash de uso geral. Isso significa que deve ser rápido, porque também é usado para criar somas de verificação (que devem processar gigabytes de dados). A velocidade diminui diretamente o tempo de força bruta e, mesmo com senhas com sal, ainda é relativamente fácil quebrar strings curtas individuais. Sais protegem apenas contra tabelas de arco-íris.

Em vez disso, use PBKDF2. É destinado especificamente para senhas, o que significa que é relativamente lento para calcular o comprimento médio da senha. Leva muito mais tempo para obter força bruta e é praticamente impossível quebrar senhas mais longas armazenadas com ele. Você pode usar a implementação de JavaScript ou usar uma implementação do lado do servidor.

Para fazer uso completo do PBKDF2, você &’ deverá implementar algum tipo de padrão de senha para o seu site. Você não precisa exigir que todos tenham cifrões e números; o comprimento é muito mais importante do que qualquer outra coisa. Tente impor senhas de 8 a 12 caracteres, no mínimo.

Uma lista de verificação final

Para encerrar, aqui está uma lista de verificação de segurança para ter certeza de que está tudo pronto:

  • Evite usar senhas e mude para OAuth, se possível.
  • Nunca armazene senhas em texto simples em qualquer banco de dados, registro ou arquivo e nunca as transmita por conexões HTTP.
  • < li> Senhas de hash com uma função hash segura como PBKDF2 ou SHA256.
  • Sempre adicione um salt aleatório aos hashes de senha e armazene-o junto com o hash.
  • Evite usar MD5 ou SHA1 . (Ambos estão corrompidos e não são seguros.)
  • Aplique padrões decentes de senha para os usuários do seu site. (O comprimento é a chave aqui.)
  • O ideal é manter o seu servidor totalmente alheio às senhas em texto simples executando o hash no lado do cliente. Esta proteção por senha à prova de futuro, mesmo no caso de um invasor obter acesso total à memória do seu servidor.
  • Certifique-se de que o próprio servidor esteja seguro bloqueando o acesso SSH e mantendo tudo atualizado, então você provavelmente irá nunca tenha esse problema em primeiro lugar.

Via: How to Geek

Nenhum comentário