This article is an automated machine-translation of an article in English. We know the translation isn't perfect, but we hope it's useful for people who don't read English.

Serious Segurança: Como armazenar senhas de seus usuários de forma segura

Filed Under: Adobe, Cryptography, Featured

Você provavelmente não perca a notícia - e as conseqüências que se seguiram - sobre a recente violação de dados da Adobe.

Não só foi uma das maiores violações de bases de dados de nome de usuário que nunca, com 150 milhões de registros expostos, foi também um dos mais embaraçoso.

Os dados vazaram revelou que a Adobe tinha sido o armazenamento de senhas de seus usuários ineptly - algo que foi surpreendente, porque o armazenamento de senhas muito mais segurança não teria sido mais difícil.

Seguindo o nosso famoso artigo explicando o Adobe fez de errado, um número de leitores nos perguntou: "Por que não publicar um artigo mostrando o resto de nós como fazê-lo direito?"

Aqui está!

Só para esclarecer: este artigo não é um tutorial de programação com exemplo de código que você pode copiar para usar em seu próprio servidor.

Em primeiro lugar, não sei se seu está utilizando PHP, MySQL, C #, Java, Perl, Python ou qualquer outra coisa, e por outro lado, existem muitos artigos já disponíveis, que lhe diz o que fazer com senhas.

Pensávamos que iríamos explicar, em seu lugar.

Tentativa One - armazenar as senhas não criptografadas

Sobre os motivos que você pretende - e, de fato, você deveria - para evitar que as senhas de seus usuários de serem roubados, em primeiro lugar, é tentador apenas para manter seu banco de dados do usuário em forma diretamente utilizável, como esta:

Se você estiver executando uma rede pequena, com apenas alguns usuários que você sabe bem, e quem lhe apoio em pessoa, você pode até considerar-se uma vantagem para armazenar senhas não criptografadas.

Dessa forma, se alguém se esquece sua senha, você pode simplesmente olhar para cima e dizer-lhes o que é.

Não faça isso, pela simples razão de que quem começa a espreitar o arquivo imediatamente sabe como logar como qualquer usuário.

Pior ainda, eles recebem um vislumbre do tipo de senha que cada usuário parece favorecer, o que poderia ajudá-los a imaginar o seu caminho em outras contas pertencentes a esse usuário.

Alfred, por exemplo, passou para o seu nome seguido de um número de seqüência de curto, Davi usou uma data que provavelmente tem algum significado pessoal, Eric Cleese seguiu um tema Monty Python, enquanto Charlie e Pato não parecem se importar em tudo.

A questão é que nem você, nem qualquer um dos seus administradores de sistemas semelhantes, deve ser capaz de olhar para cima a senha de um usuário.

Não é uma questão de confiança, é sobre a definição: a senha deve ser como um PIN, tratada como um detalhe de identificação pessoal, que é ninguém mais do negócio.

Tentativa Two - criptografar as senhas no banco de dados

A criptografia de senhas soa muito melhor.

Você pode até mesmo mandar a chave de decodificação para o banco de dados armazenado em outro servidor, se o servidor de verificação de senha para recuperá-lo somente quando necessário, e sempre apenas mantê-lo na memória.

Dessa forma, as senhas dos usuários nunca precisam ser gravados em disco em forma não criptografada, você não pode vê-los acidentalmente no banco de dados, e se os dados de senha deve ser roubado, que seria apenas repolho picado para os bandidos.

Esta é a abordagem Adobe tomou, terminando com algo semelhante a isto:

→ Para os dados de exemplo acima escolhemos o desespero chave criptografada e cada uma das senhas com reta DES . Usando DES por nada no mundo real é uma má idéia, porque ela só usa chaves de 56 bits, ou no valor de sete dos personagens. Apesar de 56 bits dá perto de 100 mil milhões de milhões de senhas possíveis, ferramentas de cracking modernas podem passar por isso muitas senhas DES dentro de um dia.

Você pode considerar este tipo de criptografia simétrica uma vantagem, porque você automaticamente pode re-criptografar todas as senhas no banco de dados se algum dia você decidir mudar a chave (você pode até ter políticas que exigem isso), ou mudar para um algoritmo mais seguro manter à frente de ferramentas de cracking.

Mas não criptografar seus bancos de dados de senha reversível assim.

Você ainda não resolveu o problema mencionado na tentativa One, ou seja, que nem você, nem qualquer um dos seus administradores de sistema colegas, deve ser capaz de recuperar a senha de um usuário.

Pior ainda, se criminosos conseguiram roubar o seu banco de dados e para adquirir a senha ao mesmo tempo, por exemplo, entrando em seu servidor remotamente, em seguida, tentar dois apenas se transforma em uma tentativa.

Pela maneira, os dados de palavra-chave acima tem ainda um outro problema, nomeadamente que foi utilizado DES, de tal maneira que a mesma palavra-passe produz os mesmos dados de cada vez.

Podemos dizer, portanto, dizer automaticamente que Charlie e Pato têm a mesma senha, mesmo sem a chave de decodificação, que é um vazamento de informações desnecessárias - como o fato de que o comprimento dos dados criptografados nos dá uma pista sobre o comprimento da senha criptografada .

Vamos, portanto, insistir sobre os seguintes requisitos:

  1. Senhas dos usuários não deve ser recuperado a partir do banco de dados.
  2. Idêntico, ou mesmo semelhante, as senhas devem ter diferentes hashes.
  3. O banco de dados deve dar nenhuma sugestão quanto ao comprimento de senha.

Tentativa Três - o hash de senhas

Uma exigência acima especifica que "as senhas dos usuários não deve ser recuperado a partir do banco de dados."

À primeira vista, este parece exigir algum tipo de criptografia "não-reversível", que soa algo entre impossível e inútil.

Mas isso pode ser feito com o que é conhecido como um hash criptográfico, que leva uma entrada de comprimento arbitrário, e mistura-se os bits de entrada em uma espécie de sopa digital.

Como ele é executado, as cepas algoritmos fora de uma quantidade fixa de dados de saída aleatória de aparência, terminando com um hash que atua como uma impressão digital para a sua entrada.

Matematicamente, um hash é uma função one-way: você pode trabalhar com o hash de qualquer mensagem, mas você não pode ir para trás a partir do hash final para os dados de entrada.

Um hash criptográfico é cuidadosamente projetado para resistir até mesmo tentativas deliberadas de subvertê-la, por misturar, picar, trituração e LIQUIDIFICAR sua entrada tão completamente que:

  • Você não pode criar um arquivo que vem com um hash pré-definido por qualquer método melhor do que o acaso.
  • Você não pode encontrar dois arquivos que "colidem", ou seja, têm o mesmo hash (seja ele qual for), por qualquer método melhor do que o acaso.
  • Você não pode trabalhar fora nada sobre a estrutura da entrada, incluindo o seu comprimento, a partir do hash sozinho.

Bem conhecido e algoritmos de hash comumente usados ​​são MD5 , SHA-1 e SHA-256 .

Destes, MD5 foi encontrado para não ter o suficiente "mix-picar-shred-e-, misture" em seu algoritmo, com o resultado que você pode encontrar dois arquivos com o mesmo hash muito mais rápido do que por acaso.

Isso significa que ele não cumprir sua promessa de criptografia originais - para não usá-lo em qualquer novo projeto.

SHA-1 é computacionalmente bastante semelhante ao MD5, e muitos especialistas consideram que em breve poderá ser encontrada a ter problemas semelhantes ao MD5 - assim você pode bem como evitá-lo .

Vamos usar SHA-256, que nos dá esta se aplicá-lo diretamente para os nossos dados da amostra (o hash foi truncado para fazê-lo se encaixam perfeitamente no diagrama):

O hashes são todas do mesmo tamanho, por isso não estão vazando todos os dados sobre o tamanho da senha.

Além disso, como podemos prever com antecedência a quantidade de dados de senha que será necessário armazenar para cada senha, agora não há desculpa para limitar a duração de uma senha de usuário. (Todos os valores SHA-256 tem 256 bits ou 32 bytes.)

Para verificar a senha de um usuário no login, continuamos submetidos a senha do usuário na memória - para que ele nunca precisa tocar o disco - e calcular seu hash.

Se o hash calculado encontra o hash armazenado, o usuário tem fachada com a senha correta, e podemos deixá-lo entrar.

Mas a tentativa Três ainda não é bom o suficiente, porque Charlie e Pato ainda tem o mesmo hash, vazamento que eles escolheram a mesma senha.

De fato, a senha de texto sairá sempre como 5E884898DA28 .. EF721D1542D8, sempre que alguém escolhe-lo.

Isso significa que os criminosos podem pré-calcular uma tabela de hashes de senhas populares - ou, ainda, dispor de espaço suficiente em disco, de todas as senhas até um determinado período - e, assim, quebrar qualquer senha já em sua lista com uma única pesquisa de banco de dados.

Tentativa Four - sal e haxixe

Podemos adaptar o hash que sai para cada senha, misturando alguns dados adicionais conhecidos como sal, assim chamado porque "estações" a saída de hash.

O sal também é conhecido como um nonce, que é a abreviação de "número usado uma vez."

Simplificando, podemos gerar uma seqüência aleatória de bytes que incluímos em nosso cálculo de hash com a senha real.

A maneira mais fácil é colocar o sal na frente da senha e haxixe a cadeia de texto combinado.

O sal não é uma chave de criptografia, para que ele possa ser armazenado no banco de dados a senha junto com o nome do usuário - que serve apenas para impedir que dois usuários com a mesma senha recebendo o mesmo hash.

Para que isso aconteça eles teriam a mesma senha eo mesmo sal, para se usar 16 bytes ou mais de sal, a chance de isso acontecer é pequena o suficiente para ser ignorada.

Nosso banco de dados agora se parece com isso (os sais de 16 bytes e os hashes foram truncados para caber perfeitamente):

Os hashes nesta lista, sendo o último campo em cada linha, são calculados através da criação de uma cadeia de texto que consiste no sal seguido pela senha, e calcular seu hash SHA-256 - para que Charlie e Pato agora ficar completamente diferentes dados de senha.

Certifique-se de escolher sais aleatórios - nunca use um contador, como 000001, 000002, e assim por diante, e não usar um gerador de números aleatórios de baixa qualidade como C do random ().

Se você fizer isso, seus sais podem coincidir com os de outros bancos de dados de senhas que você mantém, e poderia em qualquer caso, ser previsto por um invasor.

Usando suficientemente muitos bytes de uma fonte decente de números aleatórios - se você puder, use CryptoAPI no Windows ou / dev / urandom em sistemas Unix-like - Você é tão bom como garantia de que cada sal é único e, portanto, que é realmente um "número usado uma vez."

Are we there yet?

Quase, mas não completamente.

Embora tenhamos satisfeito nossos três requisitos (não-reversibilidade, não hashes repetidas e nenhum indício de comprimento password), o hash que escolhemos - um único SHA-256 de sal + senha - pode ser calculado muito rapidamente.

Na verdade, modernos servidores de hash de quebra que custam menos 20 mil dólares pode calcular 100.000.000.000 ou mais hashes SHA-256 a cada segundo.

Precisamos desacelerar as coisas um pouco para bloquear os crackers.

Tentativa Five - hash de alongamento

A natureza de um meio de hash criptográficas que os atacantes não podem ir para trás, mas com um pouco de sorte - e algumas escolhas de senha pobres - que muitas vezes pode conseguir o mesmo resultado simplesmente tentando ir para a frente e outra vez.

De fato, se os bandidos conseguiram roubar o seu banco de dados de senha e pode trabalhar off-line, não há limite que não seja o poder de CPU para a rapidez com que podem adivinhar senhas e ver como eles hash.

Por isso, queremos dizer que eles podem tentar combinar cada palavra em um dicionário (ou todas as senhas de AA para AA .. ZZ .. ZZ) com cada sal em seu banco de dados, calculando os hashes e ver se eles se todos os acessos.

E dicionários de senhas, ou algoritmos para gerar senhas para rachaduras, tendem a ser organizados de modo que as senhas mais comumente escolhidos sair o mais cedo possível.

Isso significa que os usuários que optaram uninventively tenderá a ficar rachado mais cedo.

→ Note-se que mesmo em um milhão de milhões de testes hash de senha por segundo, uma senha bem escolhida vai ficar fora do alcance praticamente indefinidamente. Há mais de mil milhões de milhões de milhões de senhas de 12 caracteres com base no conjunto de caracteres A-Za-z0-9.

Assim, faz sentido para abrandar ataques offline executando nosso algoritmo de hash de senha como um circuito que exige milhares de cálculos de hash individuais.

Isso não vai torná-lo tão lento para verificar a senha de um usuário individual durante o login que o usuário vai reclamar, ou mesmo notar.

Mas ele vai reduzir a taxa em que um bandido pode realizar um ataque offline, em proporção direta com o número de iterações que você escolher.

No entanto, não tente inventar o seu próprio algoritmo de hash repetidas.

Escolha uma destas três mais conhecidos: PBKDF2 , bcrypt ou Scrypt .

Vamos recomendar PBKDF2 aqui porque é baseado em hash primitivas que satisfazem várias normas nacionais e internacionais.

Vamos recomendo usá-lo com o HMAC-SHA-256 algoritmo de hash, repetida 10 mil vezes ou mais.

HMAC-SHA-256 é uma maneira especial de usar o algoritmo SHA-256, que não é apenas um hash diretamente, mas permite que o hash para ser combinados de forma abrangente com uma chave ou de sal:

  • Pegue uma chave aleatória ou K sal, e virar alguns pedaços, dando K1.
  • Calcule o hash SHA-256 da K1, mais os seus dados, dando-H1.
  • Inverter outro conjunto de bits de K, dando K2.
  • Calcule o hash SHA-256 da K2 mais H1, dando o hash final, H2.

Em suma, você hash de uma chave mais a sua mensagem e, em seguida, refazer uma versão permutado da chave, mais o primeiro hash.

Em PBKDF2 com 10.000 iterações, alimentamos a senha do usuário e nosso sal em HMAC-SHA-256 e fazer o primeiro dos 10 mil loops.

Então, nós alimentamos a senha eo previamente calculado HMAC de hash de volta para HMAC-SHA-256 para os restantes 9.999 vezes em volta do loop.

Toda vez que volta do loop, a última saída é XORed com o anterior para manter a correr "acumulador de hash", quando estamos a fazer, o acumulador torna-se o hash PBKDF2 final.

Agora precisamos adicionar a contagem de iteração, o sal ea PBKDF2 de hash final para o nosso banco de dados de senha:

À medida que o poder de computação disponível para os atacantes aumenta, você pode aumentar o número de iterações que você usa - por exemplo, dobrando a contagem de cada ano.

Quando os usuários com hashes de estilo antigo login com sucesso, você simplesmente regenerar e atualizar seus hashes usando a nova contagem de iteração. (Durante o login bem-sucedido é a única vez que você pode dizer que a senha de um usuário realmente é.)

Para os usuários que não fizeram logon em algum tempo, e cuja hashes velho agora considerado inseguro, você pode desativar as contas e forçar os usuários através de um processo de redefinição de senha, se alguma vez eles logon novamente.

A última palavra

Em resumo, aqui é a nossa recomendação mínima para o armazenamento seguro de senhas de seus usuários:

  • É um forte gerador de números aleatórios para criar um sal de 16 bytes, ou mais longos.
  • Alimente o sal ea senha no algoritmo PBKDF2.
  • Use HMAC-SHA-256 como o hash núcleo dentro PBKDF2.
  • Realizar 10.000 iterações ou mais.
  • Tome 32 bytes (256 bits) de saída do PBKDF2 como o hash de senha final.
  • Guarde a contagem de iteração, o sal eo hash final em seu banco de dados de senha.

Faça o que fizer, não tente a tricotar o seu próprio algoritmo de armazenamento de senha.

Ele não terminou bem para a Adobe, e é improvável que acabar bem para você.

Imagem da lupa esboço cortesia de Shutterstock .

You might like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

About the author

Paul Ducklin is a passionate security proselytiser. (That's like an evangelist, but more so!) He lives and breathes computer security, and would be happy for you to do so, too. Paul won the inaugural AusCERT Director's Award for Individual Excellence in Computer Security in 2009. Follow him on Twitter: @duckblog