Skip to content

Instantly share code, notes, and snippets.

@tompazourek
Last active August 29, 2015 14:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tompazourek/c707bc89162140acd03b to your computer and use it in GitHub Desktop.
Save tompazourek/c707bc89162140acd03b to your computer and use it in GitHub Desktop.
// 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;
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