Last active
August 29, 2015 14:16
-
-
Save tompazourek/c707bc89162140acd03b to your computer and use it in GitHub Desktop.
This file contains 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
// User entity: | |
class User { | |
// ... | |
public Password Password { get; set; } | |
} | |
// register new user: | |
var user = new User(); | |
user.Password = new Password(formPassword); | |
// verify user's password | |
var user = Db.FindUserByUsername(formUsername); | |
if (user != null && user.Password.VerifyPassword(formPassword)) | |
{ | |
return user; | |
} | |
return null; |
This file contains 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
using System; | |
using System.Collections.Generic; | |
using System.Diagnostics; | |
using System.Linq; | |
using System.Security.Cryptography; | |
using System.Text; | |
namespace Domain.ValueObjects | |
{ | |
/// <summary> | |
/// Password stored as salted hash | |
/// </summary> | |
public class Password | |
{ | |
/// <summary> | |
/// Encoding used to convert string password to sequence of bytes to hash | |
/// </summary> | |
private static readonly Encoding _encoding = Encoding.UTF8; | |
#region Data | |
public byte[] Hash { get; set; } | |
public byte[] Salt { get; set; } | |
#endregion | |
#region Constants | |
/// <summary> | |
/// Length of salt in bytes | |
/// </summary> | |
public const int SaltLength = 64; | |
/// <summary> | |
/// Length of hash in bytes | |
/// </summary> | |
public const int HashLength = 64; | |
#endregion | |
#region Constructors | |
public Password(byte[] hash, byte[] salt) | |
{ | |
Hash = hash; | |
Salt = salt; | |
} | |
public Password(string password) | |
{ | |
Salt = GenerateSalt(); | |
Hash = ComputeHash(password, Salt); | |
} | |
public Password() | |
{ | |
} | |
#endregion | |
#region Public methods | |
/// <summary> | |
/// Returns true if this password is the same as given password | |
/// </summary> | |
public bool VerifyPassword(string password) | |
{ | |
byte[] computedHash = ComputeHash(password, Salt); | |
return Hash.SequenceEqual(computedHash); | |
} | |
#endregion | |
private static byte[] ComputeHash(string password, byte[] salt) | |
{ | |
byte[] passwordBytes = _encoding.GetBytes(password); | |
byte[] hashInputBytes = passwordBytes.Concat(salt).ToArray(); | |
byte[] hashOutputBytes = ComputeHash(hashInputBytes); | |
return hashOutputBytes; | |
} | |
private static byte[] ComputeHash(byte[] input) | |
{ | |
using (var hasher = new SHA512Managed()) | |
{ | |
byte[] hashBytes = hasher.ComputeHash(input); | |
return hashBytes; | |
} | |
} | |
private static byte[] GenerateSalt() | |
{ | |
var saltBytes = new byte[SaltLength]; | |
using (var randomGenerator = new RNGCryptoServiceProvider()) | |
{ | |
randomGenerator.GetBytes(saltBytes); | |
} | |
return saltBytes; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment