Crypto of url

2

I have a SendEmail method which generates a link through HTTP request, which will send to the user's email for exchange. However for tests I fixed the user ID in this URL, but for security reasons I have to encrypt it. How do I do this?

Follow the code

Confirm Shipping Method

  public IActionResult ConfirmarEnvio(Clientes objLogin)
        {
            try
            {
                var link = HttpContext.Request.Host.Value;
                Email objEmail = new Email(_config);
                objEmail.CliCodigo = objLogin.CliCodigo;
                objEmail.CliEmail = objLogin.CliEmail;
                objEmail.link = link;
                objEmail.EnviarEmail();
                return View("Login");
            }
            catch (Exception ex)
            {

                throw ex;
            }

        }

Part of the method that generates the link:

 //From Address  
                string FromAddress = _config.GetValue<string>("From");
                string FromAdressTitle = "TesteEnvio";
                //To Address  
                string ToAddress = CliEmail;
                string ToAdressTitle = "Microsoft ASP.NET Core";
                string Subject = "Redefinição de senha";//Assunto,
                StringBuilder BodyContent = new StringBuilder();
                BodyContent.Append  ("Prezado(a)  para redefinir sua senha, por favor clique no link abaixo.");
                BodyContent.Append  ("<br/>");
                BodyContent.Append  ("Link: http://" + link + "/Accounts/RedefinicaoSenha?id=" + CliCodigo +"");

Email received however with Visible ID:

    
asked by anonymous 26.01.2018 / 17:23

1 answer

4

Responding to the initial question:

Using an md5 hash function, you could encrypt the user id:

Function Md5FromStringUTF8 :

    public static string Md5FromStringUTF8(string input)
    {
        string saida = null;
        using (System.Security.Cryptography.MD5 md5 = System.Security.Cryptography.MD5.Create())
        {
            byte[] inputBytes = System.Text.Encoding.UTF8.GetBytes(input);
            byte[] hash = md5.ComputeHash(inputBytes);
            System.Text.StringBuilder sb = new System.Text.StringBuilder();
            for (int i = 0; i < hash.Length; i++)
            {
                sb.Append(hash[i].ToString("x2"));
            }
            saida = sb.ToString();
        }

        return saida;
    }

Usage:

BodyContent.Append  ("Link: http://" + link + "/Accounts/RedefinicaoSenha?id=" + Md5FromStringUTF8(CliCodigo) +"");

However, in your controller , I would no longer run select by id, but by id md5:

'Select ... from tabela where CONVERT(VARCHAR(32), HashBytes('MD5', id), 2) = [parametro_id]'

or entity:

_context.Clientes.Where(x => Md5FromStringUTF8(x.Id) == [parametro_id]).FirstOrDefault();
  

Understand [parametro_id] as the parameter passed by Url

Suggestion for improvement based on DiegoSantos comment:

Create a class for password reset, and store it in a table. When the user makes a request to reset, you insert a record, generate the link with the id of that record, the user accessing the Url, verifies that the request is valid, and allows it to complete the process:

public class RedefinirSenha
{
    public int Id {get;set;}
    public Clientes Cliente { get; set; }
    public DateTime Data { get; set; }
    public bool IsValid { get { return (Data.AddMinutes(10) >= DateTime.Now); } }
    public string Hash { get { return Md5FromStringUTF8(Id.ToString()); } }
}
  

Considering that you are using EntityFramework, and _context is your DbContext

public IActionResult ConfirmarEnvio(Clientes objLogin)
{
    RedefinirSenha objRed = new RedefinirSenha()
    {
         Cliente = objLogin,
         Data = DateTime.Now
    };

    _context.RedefinicoesSenha.Add(objRed);
    _context.SaveChanges();


    var link = HttpContext.Request.Host.Value;
    Email objEmail = new Email(_config);
    objEmail.CliCodigo = objRed.Id; //Aqui poderia mudar a nomenclatura, já que não será mais codigo do cliente, e também já poderia passar criptografado.

    objEmail.CliEmail = objLogin.CliEmail;
    objEmail.link = link;
    objEmail.EnviarEmail();
    return View("Login");
}
  

I inserted the RedefinirSenha into action ConfirmarEnvio to give an example, I think I could put this insertion in the action where the password request is made, and the sending of the email is parameterized by that object while maintaining the cohesion of the code.

Finally, in your action RedefinicaoSenha :

public IActionResult RedefinicaoSenha(string id)
{
    RedefinirSenha objRed = _context.RedefinicoesSenha.Where(x=>x.Hash == id && x.IsValid).FirstOrDefault();

    if (objRed != null) 
    {
       //Mudar a senha do cliente com id = objRed.Cliente.id
    }
    else
    {
        //Requisição inválida
    }

    ...
}

Hope it helps, any suggestions for improvement are welcome. =]

    
26.01.2018 / 19:11