StringHasher.cs
/// <summary>
/// 实现各种字符串hash散列算法的类
/// </summary>
public class StringHasher
{
/// <summary>
/// 委托表示hash方法实现明确的散列算法
/// </summary>
/// <param name="stringToHash">待哈希的字符串</param>
/// <returns>hash散列后的字符串</returns>
private delegate string HashAlgorithMethod(string stringToHash);
/// <summary>
/// 使用MD5算法哈希字符串
/// </summary>
/// <param name="stringToHash">待哈希的字符串.</param>
/// <returns>hash散列后的字符串.</returns>
public string MD5ComputeHash(string stringToHash)
{
string results;
using (var md5Algorithm = MD5.Create())
{
results = ComputeHash(md5Algorithm, stringToHash);
DisposeAlgorithm(md5Algorithm);
}
return results;
}
/// <summary>
/// 将随机生成的SALT添加到字符串,然后使用MD5算法对字符串进行散列。
/// salt的长度与算法生成的长度相同
/// </summary>
/// <param name="stringToHash">待哈希的字符串.</param>
/// <param name="salt">Salt 用于密码.</param>
/// <returns>hash散列后的字符串.</returns>
public string MD5SaltComputeHash(string stringToHash, out string salt)
{
salt = GenerateRandomSalt(16);
return MD5ComputeHash(salt + stringToHash);
}
/// <summary>
/// 验证字符串与另一个MD5散列字符串。
/// </summary>
/// <param name="stringToVerify">要验证的字符串.</param>
/// <param name="hash">MD5生成哈希来验证.</param>
/// <returns>字符串是否匹配哈希的布尔值。</returns>
public bool MD5VerifyHash(string stringToVerify, string hash)
{
var hashedString = MD5ComputeHash(stringToVerify);
return AreTwoStringsEqual(hash, hashedString);
}
/// <summary>
/// 验证字符串与另一个MD5 SALT散列字符串。
/// </summary>
/// <param name="stringToVerify">要验证的字符串.</param>
/// <param name="hash">MD5 SALT生成的哈希来验证</param>
/// <param name="salt">Salt 用于密码</param>
/// <returns>字符串是否与SALT哈希匹配的布尔值</returns>
public bool MD5SaltVerifyHash(string stringToVerify, string hash, string salt)
{
return VerifySaltHash(stringToVerify, hash, salt, MD5ComputeHash);
}
/// <summary>
/// 使用SHA256算法Hash字符串
/// </summary>
/// <param name="stringToHash">待哈希的字符串.</param>
/// <returns>hash散列后的字符串.</returns>
public string SHA256ComputeHash(string stringToHash)
{
string results;
using (var sha256Algorithm = new SHA256Managed())
{
results = ComputeHash(sha256Algorithm, stringToHash);
DisposeAlgorithm(sha256Algorithm);
}
return results;
}
/// <summary>
/// 将随机生成的SALT添加到字符串,然后使用SHA256算法对字符串进行散列
/// salt的长度与算法生成的长度相同
/// </summary>
/// <param name="stringToHash">待哈希的字符串.</param>
/// <param name="salt">Salt 用于密码.</param>
/// <returns>hash散列后的字符串.</returns>
public string SHA256SaltComputeHash(string stringToHash, out string salt)
{
salt = GenerateRandomSalt(32);
return SHA256ComputeHash(salt + stringToHash);
}
/// <summary>
/// 验证字符串与另一个SHA256散列字符串。
/// </summary>
/// <param name="stringToVerify">要验证的字符串.</param>
/// <param name="hash">SHA256生成哈希来验证.</param>
/// <returns>字符串是否匹配哈希的布尔值.</returns>
public bool SHA256VerifyHash(string stringToVerify, string hash)
{
var hashedString = SHA256ComputeHash(stringToVerify);
return AreTwoStringsEqual(hash, hashedString);
}
/// <summary>
///验证字符串与另一个SHA256 SALT散列字符串
/// </summary>
/// <param name="stringToVerify">要验证的字符串.</param>
/// <param name="hash">SHA256 SALT生成哈希来验证</param>
/// <param name="salt">Salt 用于密码.</param>
/// <returns>字符串是否与SALT哈希匹配的布尔值</returns>
public bool SHA256SaltVerifyHash(string stringToVerify, string hash, string salt)
{
return VerifySaltHash(stringToVerify, hash, salt, SHA256ComputeHash);
}
/// <summary>
/// 使用SHA512算法哈希字符串。
/// </summary>
/// <param name="stringToHash">要hash的字符串.</param>
/// <returns>hash散列后的字符串.</returns>
public string SHA512ComputeHash(string stringToHash)
{
string results;
using (var sha512Algorithm = new SHA512Managed())
{
results = ComputeHash(sha512Algorithm, stringToHash);
DisposeAlgorithm(sha512Algorithm);
}
return results;
}
/// <summary>
/// 将随机生成的SALT添加到字符串,然后使用SHA512算法对该字符串进行散列
/// salt与算法生成的长度相同。
/// </summary>
/// <param name="stringToHash">要哈希的字符串.</param>
/// <param name="salt">Salt用于密码.</param>
/// <returns>hash散列后的字符串.</returns>
public string SHA512SaltComputeHash(string stringToHash, out string salt)
{
salt = GenerateRandomSalt(64);
return SHA512ComputeHash(salt + stringToHash);
}
/// <returns>布尔值,表示字符串是否与散列匹配。</ returns>
/// <summary>
/// 验证字符串对与另一个SHA512散列字符串。
/// </summary>
/// <param name="stringToVerify">要验证的字符串.</param>
/// <param name="hash">SHA512生成的哈希来验证.</param>
/// <returns>符串是否与散列匹配的布尔值.</returns>
public bool SHA512VerifyHash(string stringToVerify, string hash)
{
var hashedString = SHA512ComputeHash(stringToVerify);
return AreTwoStringsEqual(hash, hashedString);
}
/// <summary>
/// 将字符串与另一个SHA512 SALT散列字符串进行验证。
/// </summary>
/// <param name="stringToVerify">要验证的字符串.</param>
/// <param name="hash">SHA512 SALT生成的哈希来验证.</param>
/// <param name="salt">Salt用作密码.</param>
/// <returns>字符串是否与SALT哈希匹配的布尔值.</returns>
public bool SHA512SaltVerifyHash(string stringToVerify, string hash, string salt)
{
return VerifySaltHash(stringToVerify, hash, salt, SHA512ComputeHash);
}
/// <summary>
/// 使用传递的哈希算法计算字符串的哈希值
/// </summary>
/// <param name="hashAlgorithm">用于计算的哈希算法.</param>
/// <param name="stringToHash">要哈希的字符串.</param>
/// <returns>hash后的字符串.</returns>
private static string ComputeHash(HashAlgorithm hashAlgorithm, string stringToHash)
{
var results = hashAlgorithm.ComputeHash(Encoding.UTF8.GetBytes(stringToHash));
return BytesToHexadecimalString(results);
}
/// <summary>
///使用传递的散列算法验证字符串与另一个SALT散列字符串。
/// </ summary>
/// <param name =“stringToVerify”>要验证的字符串。</ param>
/// <param name =“hash”>生成的SALT哈希来验证。</ param>
/// <param name =“salt”>盐用于密码。</ param>
/// <param name =“algorithmToInvoke”>用于验证的哈希算法。</ param>
/// <returns>字符串是否与SALT哈希匹配的布尔值</ returns>
private static bool VerifySaltHash(string stringToVerify, string hash, string salt, HashAlgorithMethod algorithmToInvoke)
{
var hashedString = algorithmToInvoke(salt + stringToVerify);
return AreTwoStringsEqual(hash, hashedString);
}
/// <summary>
/// 处理哈希算法
/// </summary>
/// <param name="hashAlgorithm">释放的hash算法.</param>
private static void DisposeAlgorithm(HashAlgorithm hashAlgorithm)
{
hashAlgorithm.Clear();
}
/// <summary>
/// 生成指定长度的随机SALT
/// </summary>
/// <param name="saltLength">产生SALT的长度</param>
/// <returns>随机生成的SALT.</returns>
private static string GenerateRandomSalt(int saltLength)
{
var random = new RNGCryptoServiceProvider();
var salt = new byte[saltLength];
random.GetBytes(salt);
return BytesToHexadecimalString(salt);
}
/// <summary>
///将给定的字节数组转换为相应的十六进制字符串。
/// </ summary>
/// <param name =“bytesToConvert”>要转换的bytes数组。</ param>
/// <returns>相应的字符串表示。</ returns>
private static string BytesToHexadecimalString(byte[] bytesToConvert)
{
var hexaDecimalString = new StringBuilder();
for (var i = 0; i < bytesToConvert.Length; i++)
{
hexaDecimalString.Append(bytesToConvert[i].ToString("x2"));
}
return hexaDecimalString.ToString();
}
/// <summary>
///比较两个哈希值,忽略他们的大小写。
/// </ summary>
/// <param name =“hash”>要比较的第一个哈希。</ param>
/// <param name =“hashedString”>要比较的第二个哈希。</ param>
/// <returns>表示哈希是否相等的布尔值。</ returns>
private static bool AreTwoStringsEqual(string hash, string hashedString)
{
return hash.Equals(hashedString, StringComparison.OrdinalIgnoreCase);
}
}
Program.cs代码:
class Program
{
static void Main(string[] args)
{
const string stringToHash = "helloWorld";
string salt;
var hasher = new StringHasher();
var md5Hash = hasher.MD5ComputeHash(stringToHash);
Console.WriteLine("md5Hash字符串:"+md5Hash);
Console.WriteLine("md5Hash长度:" + md5Hash.Length);
Console.WriteLine("MD5VerifyHash验签:" + hasher.MD5VerifyHash(stringToHash, md5Hash));
Console.WriteLine("---------------------------------------------------");
md5Hash = hasher.MD5SaltComputeHash(stringToHash, out salt);
Console.WriteLine("md5Hash字符串:" + md5Hash);
Console.WriteLine("md5Hash长度:" + md5Hash.Length);
Console.WriteLine("MD5SaltVerifyHash验签:" + hasher.MD5SaltVerifyHash(stringToHash, md5Hash, salt));
Console.WriteLine("---------------------------------------------------");
var sha256Hash = hasher.SHA256ComputeHash(stringToHash);
Console.WriteLine("sha256Hash字符串:" + sha256Hash);
Console.WriteLine("sha256Hash长度:" + sha256Hash.Length);
Console.WriteLine("SHA256VerifyHash验签:" + hasher.SHA256VerifyHash(stringToHash, sha256Hash));
Console.WriteLine("---------------------------------------------------");
sha256Hash = hasher.SHA256SaltComputeHash(stringToHash, out salt);
Console.WriteLine("sha256Hash字符串:" + sha256Hash);
Console.WriteLine("sha256Hash长度:" + sha256Hash.Length);
Console.WriteLine("SHA256SaltVerifyHash验签:" + hasher.SHA256SaltVerifyHash(stringToHash, sha256Hash, salt));
Console.WriteLine("---------------------------------------------------");
var sha512Hash = hasher.SHA512ComputeHash(stringToHash);
Console.WriteLine("sha512Hash字符串:" + sha512Hash);
Console.WriteLine("sha512Hash长度:" + sha512Hash.Length);
Console.WriteLine("SHA512VerifyHash验签:" + hasher.SHA512VerifyHash(stringToHash, sha512Hash));
Console.WriteLine("---------------------------------------------------");
sha512Hash = hasher.SHA512SaltComputeHash(stringToHash, out salt);
Console.WriteLine("sha512Hash字符串:" + sha512Hash);
Console.WriteLine("sha512Hash长度:" + sha512Hash.Length);
Console.WriteLine("SHA512SaltVerifyHash验签:" + hasher.SHA512SaltVerifyHash(stringToHash, sha512Hash, salt));
Console.ReadKey();
}
}
运行结果如图: