using System; using System.Security.Cryptography; using System.Text; using System.Xml.Linq; namespace Neo.Afx.Security { /// /// Groups some password security methods. /// public static class SecurePassword { #region Hash(string password) /// /// Uses the SHA1 algorithm to produce a hash of the given password. /// /// The password to be hashed. /// The SHA1 hash of the password. public static string Hash(string password) { HashAlgorithm algorithm = new SHA1Managed(); return Convert.ToBase64String(algorithm.ComputeHash(Encoding.UTF8.GetBytes(password))); } #endregion #region Hash(string password, string salt) /// /// Creates a salted hash of the given value. /// /// The password to be hashed. /// The salt to be applied. /// A salted hash of the given value. public static string Hash(string password, string salt) { return Hash(String.Concat(password, salt)); } #endregion #region CreateSalt /// /// Creates a random salt value of size 7. /// /// A random salt value. public static string CreateSalt() { return CreateSalt(7); } /// /// Creates a random salt value. /// /// The size of the salt value. /// A random salt value. public static string CreateSalt(int size) { // Generate a cryptographic random number var rng = new RNGCryptoServiceProvider(); var buff = new byte[size]; rng.GetBytes(buff); // Return a Base64 string representation of the random number return Convert.ToBase64String(buff); } #endregion #region Obfuscate(string password, string salt, string challenge) /// /// Obfuscates the specified password using the given salt and challenge values. /// /// The password to be obfuscated. /// The salt value to be used. /// The challenge value to be used. /// An obfuscated password. public static string Obfuscate(string password, string salt, string challenge) { string passwordHash = Hash(password, salt); return Hash(passwordHash, challenge); } #endregion #region CreateSecureCredentials /// /// Creates secure credentials from the given password and challenge token. /// /// The challenge token containing the salt and challenge values to be parsed. /// The password to be secured. /// The secure credentials. public static string CreateSecureCredentials(XElement challengeToken, string password) { var salt = challengeToken.Attribute("Salt"); var challenge = challengeToken.Attribute("Challenge"); if(salt == null || challenge == null) { return null; } var passwordHash = Hash(password); return Obfuscate(passwordHash, salt.Value, challenge.Value); } #endregion } }