Dica Rápida: Protegendo senhas com BCrypt.Net
Tags: csharp, dotnet, security, braziliandevs
Published: 2020-08-02 19:06:08

Olá!

Esta Dica Rápida surgiu de um [tweet](https://twitter.com/luizcarlosfaria/status/1289600627366981632) do Luiz Carlos Faria sobre um vazamento que expôs diversos dados de usuários do site Vakinha.

Isso me fez lembrar que, infelizmente, nem todos trabalhamos com senhas criptografadas, algo que, em um cenário de vazamento, é um desastre em potencial.

Pensando nisso, resolvi escrever esta dica simples para a geração de senhas mais seguras utilizando uma biblioteca chamada [Bcrypt.Net-Next](https://www.nuget.org/packages/BCrypt.Net-Next/)

O processo é bastante simples e a biblioteca abstrai muito bem o algoritmo utilizado para proteger as senhas. Abaixo, segue um código de exemplo:

```c#
using System;
using BCrypt.Net;
using static BCrypt.Net.BCrypt;

namespace DicaRapida.Bcrypt.Password
{
    class Program
    {
        private const int WorkFactor = 12;

        static void Main(string[] args)
        {
            Console.WriteLine("Digite sua nova senha: ");
            var cleanPassword = Console.ReadLine();
            var hashedPassword = HashPassword(cleanPassword, WorkFactor);
            Console.WriteLine($"O hash para sua senha é: {hashedPassword}");
            
            Console.WriteLine("Confirme sua nova senha: ");
            var passwordsMatch = Verify(Console.ReadLine(), hashedPassword);
            Console.WriteLine($"A verificação foi {(passwordsMatch ? "positiva" : "negativa")}");
        }
    }
}
```

Parece simples. Não? E é mesmo!

Tudo o que você precisa fazer em sua aplicação é gerar um hash a partir da senha em *plain text* através do método `HashPassword`, e persistí-lo. Toda vez que o usuário informar sua senha no processo de logon, basta recuperar o hash armazenado e confrontá-lo com a senha informada pelo método `Verify`, que vai gerar um hash da senha informada pelo usuário em tempo de execução e comparar com a senha persistida.

Uma curiosidade sobre este algoritmo é que, antes de gerar um hash, ele gera o que chamamos de *salt*. O *salt* é uma partícula gerada randomicamente, que é adicionada à frente da senha em *plain text* antes de o algoritmo de fato compor o hash final. Este é um modo de aumentar a complexidade das senhas informadas pelos usuários, tornando ainda mais difícil identificá-las. 

> **Nota:** repare que existe uma constante chamada `WorkFactor`, cujo valor é 12.  Este valor representa uma potência de 2 que indica o número de iterações que será realizado pelo algoritmo para gerar o *salt* antes de retornar um hash. Este `WorkFactor`é também conhecido como `CostFactor` ou apenas `Cost`, porque indica o custo de processamento para gerar o *salt*. Ou seja, quanto maior o valor, maior o tempo necessário para a geração do *salt*, e maior o custo computacional da operação. Um valor minimamente razoável para o `WorkFactor` é 10 (que vai produzir 1024 iterações). Pessoalmente, custumo usar 12 (4096 iterações) por notar um custo-benefício razoável nas aplicações que escrevi (onde o custo é o computacional e o benefício é o nível de segurança do *salt* e, consequentemente, do hash). Conforme a passagem do tempo, este valor deve ser incrementado para acompanhar as melhorias do hardware!

Legal. Não?

Com esta simples dica, caso seu banco de dados seja exposto de alguma forma, as senhas dos usuários estarão em um formato bem difícil de quebrar, e que, costumeiramente, é o suficiente para evitar que indivíduos indesejados acessem sua aplicação usando os dados vazados.

Caso queira testar o código acima, consulte meu [GitHub](https://github.com/wsantosdev/dica-rapida-bcrypt).


Gostou? Me deixe saber pelos indicadores. Dúvidas? Me pergunte pelos comentários que responderei assim que possível.


Até a próxima!



> Referências:
> [bcrypt.net - next (GitHub)](https://github.com/BcryptNet/bcrypt.net)