BCrypt é um bom algoritmo de hash para usar em c #? Onde posso encontrá-lo? [fechadas]

129

Eu li que, ao fazer o hash de uma senha, muitos programadores recomendam o uso do algoritmo BCrypt.

Estou programando em c # e gostaria de saber se alguém sabe de uma boa implementação para BCrypt? Encontrei esta página , mas realmente não sei se é falsa ou não.

O que devo saber ao escolher um esquema de hash de senha? O BCrypt é uma implementação 'boa'?

Svish
fonte

Respostas:

148

Primeiro, alguns termos que são importantes:

Hashing - O ato de pegar uma string e produzir uma sequência de caracteres que não podem ser revertidos para a string original.

Criptografia simétrica - (geralmente chamada de 'criptografia') - O ato de pegar uma string e produzir uma sequência de caracteres que podem ser descriptografados para a string original através do uso da mesma chave de criptografia que a criptografou.

Tabela Arco-Íris - uma tabela de pesquisa que contém todas as variações de caracteres com hash em um algoritmo de hash específico.

Salt - uma string aleatória conhecida anexada à string original antes de ser hash.

Para o .NET Framework, o Bcrypt ainda não possui uma implementação de referência verificada . Isso é importante porque não há como saber se há falhas sérias em uma implementação existente. Você pode obter uma implementação do BCrypt for .NET aqui . Não sei o suficiente sobre criptografia para dizer se é uma implementação boa ou ruim. A criptografia é um campo muito profundo. Não tente criar seu próprio algoritmo de criptografia . Seriamente.

Se você estiver implementando sua própria segurança de senha (suspiro), precisará fazer várias coisas:

  1. Use um algoritmo de hash relativamente seguro .
  2. Sal cada senha antes de ser hash.
  3. Use um sal longo e exclusivo para cada senha e armazene o sal com a senha.
  4. Exija senhas fortes .

Infelizmente, mesmo se você fizer tudo isso, um hacker determinado ainda pode descobrir as senhas, isso levaria muito tempo. Esse é o seu principal inimigo: o tempo .

O algoritmo bcrypt funciona porque são necessárias cinco ordens de magnitude mais para o hash de uma senha que o MD5 ; (e ainda muito mais longo que o AES ou o SHA-512). Isso força o hacker a gastar muito mais tempo para criar uma tabela de arco-íris para procurar suas senhas, tornando muito menos provável que suas senhas corram o risco de serem invadidas.

Se você estiver salgando e hash suas senhas e cada sal for diferente, um hacker em potencial precisará criar uma tabela arco-íris para cada variação de sal , apenas para ter uma tabela arco-íris para uma senha salgada + com hash. Isso significa que, se você possui 1 milhão de usuários, um hacker precisa gerar 1 milhão de tabelas arco-íris. Se você estiver usando o mesmo sal para todos os usuários, o hacker precisará gerar apenas 1 tabela arco-íris para invadir com êxito o seu sistema.

Se você não está salgando suas senhas, tudo o que um invasor precisa fazer é acessar uma tabela Rainbow existente para todas as implementações existentes (AES, SHA-512, MD5) e apenas verificar se uma delas corresponde ao hash. Isso já foi feito , um invasor não precisa calcular essas tabelas do Rainbow .

Mesmo com tudo isso, você deve usar boas práticas de segurança . Se eles puderem usar com êxito outro vetor de ataque (XSS, SQL Injection, CSRF, etc. ) em seu site, uma boa segurança de senha não importa. Parece uma declaração controversa, mas pense bem: se eu posso obter todas as informações do usuário por meio de um ataque de injeção de SQL, ou posso permitir que seus usuários me forneçam seus cookies através do XSS, não importa a qualidade da sua senha. segurança é .

Outros recursos:

  1. Jeff Atwood: criptografia .NET simplificada (excelente para uma visão geral do hash)
  2. Jeff Atwood: Acabei de entrar como você
  3. Jeff Atwood: Você provavelmente está armazenando senhas incorretamente
  4. Jeff Atwood: Speed ​​Hashing

Nota: Por favor, recomende outros bons recursos. Devo ter lido uma dúzia de artigos de dezenas de autores, mas poucos escrevem tão claramente sobre o assunto quanto Jeff. Edite os artigos à medida que os encontrar.

George Stocker
fonte
talvez adicionar ao seu parágrafo sal que um sal devem ser escolhidos aleatoriamente
Jacco
2
@Jacco Boa chamada, acrescentou. Embora isso não seja tão importante. Você pode simplesmente usar o registro de data e hora do login para o salt. A diferença que faz é que o atacante precisa recalcular a tabela do arco-íris para cada sal. É isso que dificulta, não que seja escolhido aleatoriamente. Torná-lo aleatório adicionaria outra camada de obsfucação, mas isso será inútil quando o invasor puder ver seu banco de dados (que é o problema que causa toda nossa dor de cabeça em primeiro lugar).
precisa
3
Na verdade, o sal não precisa ser secreto, o único para cada instância. Como o único (como no mundo inteiro) não é possível, o aleatório é a próxima melhor coisa. Além disso, o timestamp não é um bom sal, pois não há entropia suficiente.
Jacco
7
Eu aceitaria sua declaração "Se eles puderem usar injeção XSS ou SQL com êxito, uma boa segurança de senha não importará". Pelo contrário, se eles conseguirem injetar XSS ou SQL com sucesso no site, uma boa segurança de senha é ainda mais importante. A chave aqui é "defesa em profundidade" - você deve aumentar a segurança, tanto quanto possível, em todas as camadas do seu aplicativo.
Jammycakes #
2
@jammycakes Absolutamente; meu argumento foi perdido: você não pode simplesmente dizer: 'Ei, nós misturamos nossas senhas, "estamos bem"!'
George Stocker 23/10
74

Você não deve usar o BCrypt no .NET. Você deve usar o PBKDF2 como está na implementação da estrutura .NET integrada. É a única implementação verificada criptograficamente disponível gratuitamente no .NET, além de ser o algoritmo recomendado pelo NIST .

O StackId usou o BCrypt anteriormente e mudou-se para PBKDF2 por esse mesmo motivo:

Para os curiosos, estamos usando hash de senhas com PBKDF2. O código relevante está aqui ( http://code.google.com/p/stackid/source/browse/OpenIdProvider/Current.cs#1135 ), através de algumas camadas indiretas. Em uma iteração anterior, estávamos usando o BCrypt; mas mudou-se para PBKDF2 à medida que é incorporado à estrutura .NET, enquanto o BCrypt exigiria que verificássemos uma implementação (não é uma tarefa pequena).

Kevin Montrose, 27 de maio de 2011

(Link atualizado no GitHub)

Edit: O significado de verificado em termos criptográficos parece não ser facilmente entendido, uma implementação verificada significa que foi criptograficamente comprovado que foi implementado sem erros. O custo disso pode facilmente chegar a US $ 20.000 ou mais. Lembro-me disso quando estava pesquisando sobre o OpenSSL e li onde eles declararam que não concluíram todo o processo de verificação, mas se você precisar verificar completamente, eles podem apontar o caminho certo e os custos mencionados. Alguns requisitos governamentais incluem mandatos para algoritmos de criptografia verificados.

As implementações de bcrypt no .NET não foram verificadas. Usando uma implementação de criptografia não verificada, você não pode ter certeza absoluta de que não há falhas maliciosas intencionais, como permitir uma backdoor no que é criptografado ou falhas de implementação não intencionais que resultam em dados criptograficamente inseguros.

Edição de 2014: Para quem questionou a imperatividade de usar algoritmos criptográficos verificados, observe a devastação causada pelo hack de coração explorado no OpenSSL. Esse é o custo do uso de uma implementação não verificada. É seguro .... até você descobrir que qualquer pessoa pode apenas ler todo o conteúdo da memória do seu servidor.

O autor da mudança que introduziu o Heartbleed, Robin Seggelmann, afirmou que "perdeu a validação de uma variável que contenha um comprimento" e negou qualquer intenção de enviar uma implementação falha. Após a divulgação da Heartbleed, Seggelmann sugeriu se concentrar no segundo aspecto, afirmando que o OpenSSL não é revisado por pessoas suficientes.

Esta é a definição de uma implementação não verificada. Mesmo o menor defeito pode resultar em uma paralisação de toda a segurança.

Edição de 2015: removido o idioma baseado em recomendações e substituído por absolutos. Comentário original incorporado de Kevin Montrose para a posteridade.

Chris Marisic
fonte
25
Para citar o comentário vinculado: "[passamos] para o PBKDF2 conforme ele é incorporado à estrutura .NET, enquanto o BCrypt exigiria que verificássemos uma implementação". Observe que o comentário não diz que o algoritmo é melhor, apenas que o SE Dev Team considera a implementação interna do PBKDF2 mais confiável do que uma biblioteca externa (que é, em última análise, uma chamada de julgamento).
Piskvor saiu do prédio em
3
@Piskvor Atualizei minha resposta. Não se trata do que a equipe de SO considera segura, mas de um julgamento entre segurança inerentemente comprovada ou esperançosamente segura. O último quando se trata de criptografia é inaceitável.
Chris Marisic
6
Gostaria de saber como SO migrou todas as senhas de hash bcrypt para os novos hashes? Eles não precisariam das senhas brutas para fazer o hash usando o novo algoritmo?
Dharmendar Kumar 'DK'
8
@DK Nem acho que você precise pedir para redefinir suas senhas. No próximo logon (onde eles fornecem sua senha em texto sem formatação), você pode fazer isso, acredito.
224168 Matt Kocaj
12
Este é um péssimo conselho e estou surpreso que tenha tantos votos positivos. Verificar uma implementação BCrypt em uma linguagem gerenciada é muito, muito mais trivial do que verificar algo como uma implementação SSL inteira no C. Heartbleed é completamente irrelevante; seria melhor mencionar algo como problemas de coação do tipo PHP com verificações de igualdade de hash. Além disso, embora amplamente adequado em termos práticos, o PBKDF2 é um KDF, não um algoritmo de hash de senha, enquanto o BCrypt é mais adequado. Independentemente disso, ele faria muito mais sentido usar Argon2 estes dias de qualquer maneira, para o qual existe uma biblioteca bem testado C #
polinomial