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
}
}