Hash and salt passwords in C#

后端 未结 14 1823
野趣味
野趣味 2020-11-22 04:00

I was just going through one of DavidHayden\'s articles on Hashing User Passwords.

Really I can\'t get what he is trying to achieve.

Here is his code:

<
相关标签:
14条回答
  • 2020-11-22 04:11
    create proc [dbo].[hash_pass] @family nvarchar(50), @username nvarchar(50), @pass nvarchar(Max),``` @semat nvarchar(50), @tell nvarchar(50)
    
    as insert into tbl_karbar values (@family,@username,(select HASHBYTES('SHA1' ,@pass)),@semat,@tell)
    
    0 讨论(0)
  • 2020-11-22 04:12

    I read all answers and I think those enough, specially @Michael articles with slow hashing and @CodesInChaos good comments, but I decided to share my code snippet for hashing/validating that may be useful and it does not require [Microsoft.AspNet.Cryptography.KeyDerivation].

        private static bool SlowEquals(byte[] a, byte[] b)
                {
                    uint diff = (uint)a.Length ^ (uint)b.Length;
                    for (int i = 0; i < a.Length && i < b.Length; i++)
                        diff |= (uint)(a[i] ^ b[i]);
                    return diff == 0;
                }
    
        private static byte[] PBKDF2(string password, byte[] salt, int iterations, int outputBytes)
                {
                    Rfc2898DeriveBytes pbkdf2 = new Rfc2898DeriveBytes(password, salt);
                    pbkdf2.IterationCount = iterations;
                    return pbkdf2.GetBytes(outputBytes);
                }
    
        private static string CreateHash(string value, int salt_bytes, int hash_bytes, int pbkdf2_iterations)
                {
                    // Generate a random salt
                    RNGCryptoServiceProvider csprng = new RNGCryptoServiceProvider();
                    byte[] salt = new byte[salt_bytes];
                    csprng.GetBytes(salt);
    
                    // Hash the value and encode the parameters
                    byte[] hash = PBKDF2(value, salt, pbkdf2_iterations, hash_bytes);
    
                    //You need to return the salt value too for the validation process
                    return Convert.ToBase64String(hash) + ":" + 
                           Convert.ToBase64String(hash);
                }
    
        private static bool ValidateHash(string pureVal, string saltVal, string hashVal, int pbkdf2_iterations)
                {
                    try
                    {
                        byte[] salt = Convert.FromBase64String(saltVal);
                        byte[] hash = Convert.FromBase64String(hashVal);
    
                        byte[] testHash = PBKDF2(pureVal, salt, pbkdf2_iterations, hash.Length);
                        return SlowEquals(hash, testHash);
                    }
                    catch (Exception ex)
                    {
                        return false;
                    }
                }
    

    Please pay attention SlowEquals function that is so important, Finally, I hope this help and Please don't hesitate to advise me about better approaches.

    0 讨论(0)
  • 2020-11-22 04:16

    I created a class that has the following method:

    1. Create Salt

    2. Hash Input

    3. Validate input

      public class CryptographyProcessor
      {
          public string CreateSalt(int size)
          {
              //Generate a cryptographic random number.
              RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
              byte[] buff = new byte[size];
              rng.GetBytes(buff);
              return Convert.ToBase64String(buff);
          }
      
          public string GenerateHash(string input, string salt)
          { 
              byte[] bytes = Encoding.UTF8.GetBytes(input + salt);
              SHA256Managed sHA256ManagedString = new SHA256Managed();
              byte[] hash = sHA256ManagedString.ComputeHash(bytes);
              return Convert.ToBase64String(hash);
          }
      
          public bool AreEqual(string plainTextInput, string hashedInput, string salt)
          {
              string newHashedPin = GenerateHash(plainTextInput, salt);
              return newHashedPin.Equals(hashedInput); 
          }
      }
      
    0 讨论(0)
  • 2020-11-22 04:16

    Use the System.Web.Helpers.Crypto NuGet package from Microsoft. It automatically adds salt to the hash.

    You hash a password like this: var hash = Crypto.HashPassword("foo");

    You verify a password like this: var verified = Crypto.VerifyHashedPassword(hash, "foo");

    0 讨论(0)
  • 2020-11-22 04:19

    In answer to this part of the original question "Is there any other C# method for hashing passwords" You can achieve this using ASP.NET Identity v3.0 https://www.nuget.org/packages/Microsoft.AspNet.Identity.EntityFramework/3.0.0-rc1-final

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using Microsoft.AspNet.Identity;
    using System.Security.Principal;
    
    namespace HashTest{
    
    
        class Program
        {
            static void Main(string[] args)
            {
    
                WindowsIdentity wi = WindowsIdentity.GetCurrent();
    
                var ph = new PasswordHasher<WindowsIdentity>();
    
                Console.WriteLine(ph.HashPassword(wi,"test"));
    
                Console.WriteLine(ph.VerifyHashedPassword(wi,"AQAAAAEAACcQAAAAEA5S5X7dmbx/NzTk6ixCX+bi8zbKqBUjBhID3Dg1teh+TRZMkAy3CZC5yIfbLqwk2A==","test"));
    
            }
        }
    
    
    }
    
    0 讨论(0)
  • 2020-11-22 04:20

    Bah, this is better! http://sourceforge.net/projects/pwdtknet/ and it is better because ..... it performs Key Stretching AND uses HMACSHA512 :)

    0 讨论(0)
提交回复
热议问题