Last active
December 25, 2015 21:39
-
-
Save khellang/7044093 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| public class PasswordHash | |
| { | |
| private const int SaltSize = 10; | |
| private const int HashSize = 40; | |
| private const int Iterations = 10000; | |
| private PasswordHash(byte[] hashBytes, byte[] saltBytes) | |
| { | |
| HashBytes = hashBytes; | |
| SaltBytes = saltBytes; | |
| } | |
| public byte[] HashBytes { get; private set; } | |
| public byte[] SaltBytes { get; private set; } | |
| public string HashBase64 | |
| { | |
| get { return Convert.ToBase64String(HashBytes); } | |
| } | |
| public string SaltBase64 | |
| { | |
| get { return Convert.ToBase64String(SaltBytes); } | |
| } | |
| public static PasswordHash Generate(string password, int hashSize = HashSize, int saltSize = SaltSize) | |
| { | |
| using (var hasher = new Rfc2898DeriveBytes(password, saltSize, Iterations)) | |
| { | |
| return new PasswordHash(hasher.GetBytes(hashSize), hasher.Salt); | |
| } | |
| } | |
| public static PasswordHash From(string hashBase64, string saltBase64) | |
| { | |
| var hashBytes = Convert.FromBase64String(hashBase64); | |
| var saltBytes = Convert.FromBase64String(saltBase64); | |
| return From(hashBytes, saltBytes); | |
| } | |
| public static PasswordHash From(byte[] hashBytes, byte[] saltBytes) | |
| { | |
| return new PasswordHash(hashBytes, saltBytes); | |
| } | |
| public bool Verify(string password) | |
| { | |
| using (var hasher = new Rfc2898DeriveBytes(password, SaltBytes, Iterations)) | |
| { | |
| return SlowEquals(hasher.GetBytes(HashBytes.Length), HashBytes); | |
| } | |
| } | |
| [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] | |
| private static bool SlowEquals(IList<byte> a, IList<byte> b) | |
| { | |
| var diff = a.Count ^ b.Count; | |
| for (var i = 0; i < a.Count && i < b.Count; i++) | |
| { | |
| diff |= a[i] ^ b[i]; | |
| } | |
| return diff == 0; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| public class Usage | |
| { | |
| private void Register(string username, string password) | |
| { | |
| var hash = PasswordHash.Generate(password); | |
| Database.Save(new User | |
| { | |
| Username = username, | |
| PasswordHash = hash.HashBase64, | |
| Salt = hash.SaltBase64 | |
| }); | |
| } | |
| private bool Login(string username, string password) | |
| { | |
| var user = Database.Get(username); | |
| if (user == null) | |
| { | |
| return false; | |
| } | |
| return PasswordHash.From(user.PasswordHash, user.Salt).Verify(password); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment