Password encryption

5

I have an Asp.Net MVC project and would like to securely store user passwords in the database. Home The goal is to create something that can not be easily decrypted in a few hours of brute force on a PC (I'm aware that with a little more effort the password may be broken). So a simple hash would be ideal, like: MD5, SHA1, SHA2, etc. I believe that some symmetric algorithm like AES would solve the problem. Home What I have planned: Home When you create the account, the user's password is encrypted and saved to the database. HomeUponlogin,thebankpasswordwillnotbedecrypted,butthepasswordenteredbytheuserintheloginwillbeencryptedandcomparedwiththebankpassword. Disregard if the code in the image is not correct.

  

The questions are:   

     
  • Would this be a good practice?
  •   
  • AES would be the best algorithm?
      2.1. How could AES encryption be done using C #? Is there any ready method yet?
      2.2. Is there a more secure key model?
  •   
        
    asked by anonymous 15.09.2015 / 23:24

    2 answers

    11
      

    Would that be a good practice?

    No. The recommended way to protect a password is through a slow hash (PBKDF2, BCrypt, or scrypt). You are correct in saying that a fast hash is ineffective, but do you realize that using an encryption algorithm in a single direction (just encrypting, never deciphering) is almost the same thing as applying a hash?

    It would not be honest of me to say that your technique is completely useless, however - if an attacker gets access to the database and only to the database (for example, exploiting an Injection of SQL) it will be unable to recover the passwords. In fact, there is a technique called "pepper" that takes advantage of this fact to give additional protection to a hash (more details in the answer to the linked question). The problem is to base all your security solely on this premise (that the attacker will not have access to your code, even if it is just for reading).

      

    Would AES be the best algorithm?

    Neither AES nor any other symmetric encryption algorithm (such as 3DES, etc.). For even if you do not want to decipher the password in no time, an attacker who gets access to your DB and your key will not do the same "out of honor", it will undo the encryption and ready! In other words, your login is slow (because you are encrypting and comparing) and the attacker is still fast ...

    Asymmetric cipher would be marginally better (because the attacker could not simply decrypt, he would have to test password by password - because if the private key is off the server, he can only use the public key) risk of being too fast compared to a hash. In the end, a hash is really the best you can reasonably achieve, and using a pepper would help give you the additional security you sought by proposing this method (though I personally do not I tend to worry too much about it - it will depend on how sensitive your particular application is.)

      

    How could AES encryption be done a slow hash using C #? Is there any ready method yet?

    Rfc2898DeriveBytes is a native solution for PBKDF2 (there are also BCrypt and scrypt implementations for .Net, third-party I believe), you just need to adjust the parameters accordingly. An example would be:

    string pwd = senha_a_ser_hasheada;
    
    // Cria um sal aleatório de 64 bits
    byte[] salt = new byte[8];
    using (RNGCryptoServiceProvider rngCsp = new RNGCryptoServiceProvider())
    {
        // Enche o array com um valor aleatório
        rngCsp.GetBytes(salt);
    }
    
    // Escolha o valor mais alto que seja "tolerável"
    // 100 000 era um valor razoável em 2011, não sei se é suficiente hoje
    int myIterations = 100000;
    try
    {
        Rfc2898DeriveBytes k = new Rfc2898DeriveBytes(pwd, salt, myIterations);
        byte[] hash = k.getBytes(32);
        // Codifica esse hash de alguma forma e salva no BD
        // (lembre-se de salvar o salt também! você precisará dele para comparação)
    

    If you want to use a pepper , get the secret value that only exists in your code (or some configuration file) and concatenate it to the password or salt before making the hash the size if needed).

        
    16.09.2015 / 00:03
    1

    Use bcrypt: link . Read the definition of what is bcrypt: link . Home With bcrypt your passwords are already encrypted with salt / hash. Home When verifying the user when logging in, there is the VerifyPassword function that receives 2 parameters which are: password coming from the textbox and the password coming from the database; hashes are compared. Home To use, include these lines according to the chosen language:

    using Bcrypt.Net.Bcrypt -> C# 
    Imports Bcrypt.Net.Bcrypt -> VB.NET
    


    To make the password hash:

    HashPassword(senha, GenerateSalt(12)).
    

    12 is the default cost. The higher the cost, the slower it will be for rainbow tables, but also for processing the hash through your hardware and database. Home For verification:

    VerifyPassword(campo_senha, banco_senha)
    

    Example in VB.NET (can be easily ported to C #):

    If sqldatareader.Hasrows Then
       While sqldatareader.Read
       If (Bcrypt.Net.Bcrypt.Verify(txtPassword.text, 
           sqldatareader.Item("password"))) then
           MsgBox("Valid Credentials")
         else
           MsgBox("Invalid Credentials")
       End if
       End While
       sqldatareader.Close()
    End If
    

    sqldatareader: datareader that can be from mysql, sql, postgresql, etc. Home To save the password in the database use varchar (255) or nvarchar (255) in the case of sql server.

        
    24.05.2017 / 01:40