MD5 Encryption asp.net MVC

0

I have to do an encryption in a web application. I am using the following method to encrypt the password.

// Criptografa a senha
    public string GerarMD5(string Senha) {

        // criptografia MD5

        MD5 md5Hasher = MD5.Create();

        // Criptografa o valor passado
        byte[] valorCriptografado = md5Hasher.ComputeHash(Encoding.Default.GetBytes(Senha));

        for (int i = 0; i < valorCriptografado.Length; i++) {
            strBuilder.Append(valorCriptografado[i].ToString("x2"));
        }

        // retorna o valor criptografado como string
        return strBuilder.ToString();

    }

In the class where I create the account I use the following call to encrypt the password.

// Cria usuarioDTO
            UsuarioDTO usuarioDTO = new UsuarioDTO()
            {
                Nome = model.Nome,
                SobreNome = model.SobreNome,
                Email = model.Email,
                Usuario = model.Usuario,
                Senha = GerarMD5(model.Senha),
            };

            // Adiciona ao DTO
            db.Usuarios.Add(usuarioDTO);

            // Salva
            db.SaveChanges();

So far so good, it encrypts the password. My problem is when checking the hash generated with the password that the user will type, I tried the following way.

Method to check for hash:

// Verifica se o valor é compativel com o hash passado
    public bool verifyMd5Hash(string valor, string valorCriptografado)
    {
        // Criptografamos o valor passado como parâmetro
        // utilizando o mesmo método citado no artigo anterior
        string NovoValorCriptografado = GerarMD5(valor);

        // Criamos uma StringComparer para compararmos os dois hashs gerados
        StringComparer comparer = StringComparer.OrdinalIgnoreCase;

        //Se os valores forem iguais, retorna true, ou seja, o valor
        // passado corresponde ao Hash
        if (comparer.Compare(NovoValorCriptografado, valorCriptografado) == 0)
        {
            return true;
        }
        else
        {
            return false;
        }
    }

I tried this method and called it in the login class

// POST: /conta/login
    [HttpPost]
    public ActionResult Login(LoginUsuarioVM model)
    {
        // Verifica o status da model
        if (!ModelState.IsValid)
        {
            return View(model);
        }

        // Verifica se o usuário é válido


        bool isValid = false;

        using (Db db = new Db())
        {
            if (db.Usuarios.Any(x => x.Usuario.Equals(model.Usuario) && (verifyMd5Hash(x.Senha, model.Senha))))
            {
                isValid = true;
            }
        }
        if (!isValid)
        {
            ModelState.AddModelError("", "Usuário ou senha inválida.");
            return View(model);
        }
        else
        {
            FormsAuthentication.SetAuthCookie(model.Usuario, model.Lembrar);
            return Redirect(FormsAuthentication.GetRedirectUrl(model.Usuario, model.Lembrar));
        }
    }

When testing it it returns me the following error.

My logic might not make much sense, but I'd like some help, what would be the best way to check the hash for this program to work.

    
asked by anonymous 19.06.2018 / 22:01

1 answer

0

The problem is in this line of code

if (db.Usuarios.Any(x => x.Usuario.Equals(model.Usuario) && 
                         (verifyMd5Hash(x.Senha, model.Senha))))

More specifically, in the second line.

Because you are using the Any() method of a IQueryable the predicate passed by parameter to the method will be converted to SQL and LINQ To Entities (the tool that does this conversion) does not know the verifyMd5Hash .

Basically, you would need to get the user from the database and compare the hashs in memory.

var usuario = db.Usuarios.First(u => u.Usuario == model.Usuario);
if(verifyMd5Hash(usuario.Senha, model.Senha)) { }
    
19.06.2018 / 23:42