PasswordUtil.cs 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Security.Cryptography;
  5. using System.Text;
  6. using System.Threading.Tasks;
  7. using System.Web.Security;
  8. namespace Ant.Service.Utility
  9. {
  10. /// <summary>
  11. ///
  12. /// </summary>
  13. public class PasswordUtils
  14. {
  15. #region field & constructor
  16. //private static readonly Log _log = new Log(typeof(PasswordUtil));
  17. private const int saltLength = 4;
  18. public PasswordUtils() { }
  19. #endregion
  20. /// <summary>
  21. /// 对比用户明文密码是否和加密后密码一致
  22. /// </summary>
  23. /// <param name="dbPassword">数据库中单向加密后的密码</param>
  24. /// <param name="userPassword">用户明文密码</param>
  25. /// <returns></returns>
  26. public static bool ComparePasswords(string dbPassword, string userPassword)
  27. {
  28. byte[] dbPwd = Convert.FromBase64String(dbPassword);
  29. byte[] hashedPwd = HashString(userPassword);
  30. if (dbPwd.Length == 0 || hashedPwd.Length == 0 || dbPwd.Length != hashedPwd.Length + saltLength)
  31. {
  32. return false;
  33. }
  34. byte[] saltValue = new byte[saltLength];
  35. // int saltOffset = dbPwd.Length - hashedPwd.Length;
  36. int saltOffset = hashedPwd.Length;
  37. for (int i = 0; i < saltLength; i++)
  38. saltValue[i] = dbPwd[saltOffset + i];
  39. byte[] saltedPassword = CreateSaltedPassword(saltValue, hashedPwd);
  40. // compare the values
  41. return CompareByteArray(dbPwd, saltedPassword);
  42. }
  43. /// <summary>
  44. ///
  45. /// </summary>
  46. /// <param name="str"></param>
  47. /// <param name="code">16与32位加密</param>
  48. /// <returns></returns>
  49. public static string MD5_Encrypt(string str, int code)
  50. {
  51. if (code == 16) //16位MD5加密(取32位加密的9~25字符)
  52. {
  53. return FormsAuthentication.HashPasswordForStoringInConfigFile(str, "MD5").ToLower().Substring(8, 16);
  54. }
  55. if (code == 32)
  56. {
  57. return FormsAuthentication.HashPasswordForStoringInConfigFile(str, "MD5").ToLower();
  58. }
  59. return str;
  60. }
  61. /// <summary>
  62. /// 创建用户的数据库密码
  63. /// </summary>
  64. /// <param name="password"></param>
  65. /// <returns></returns>
  66. public static string CreateDbPassword(string userPassword)
  67. {
  68. byte[] unsaltedPassword = HashString(userPassword);
  69. //Create a salt value
  70. byte[] saltValue = new byte[saltLength];
  71. RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
  72. rng.GetBytes(saltValue);
  73. byte[] saltedPassword = CreateSaltedPassword(saltValue, unsaltedPassword);
  74. return Convert.ToBase64String(saltedPassword);
  75. }
  76. #region 私有函数
  77. /// <summary>
  78. /// 将一个字符串哈希化
  79. /// </summary>
  80. /// <param name="str"></param>
  81. /// <returns></returns>
  82. private static byte[] HashString(string str)
  83. {
  84. byte[] pwd = System.Text.Encoding.UTF8.GetBytes(str);
  85. SHA1 sha1 = SHA1.Create();
  86. byte[] saltedPassword = sha1.ComputeHash(pwd);
  87. return saltedPassword;
  88. }
  89. private static bool CompareByteArray(byte[] array1, byte[] array2)
  90. {
  91. if (array1.Length != array2.Length)
  92. return false;
  93. for (int i = 0; i < array1.Length; i++)
  94. {
  95. if (array1[i] != array2[i])
  96. return false;
  97. }
  98. return true;
  99. }
  100. // create a salted password given the salt value
  101. private static byte[] CreateSaltedPassword(byte[] saltValue, byte[] unsaltedPassword)
  102. {
  103. // add the salt to the hash
  104. byte[] rawSalted = new byte[unsaltedPassword.Length + saltValue.Length];
  105. unsaltedPassword.CopyTo(rawSalted, 0);
  106. saltValue.CopyTo(rawSalted, unsaltedPassword.Length);
  107. //Create the salted hash
  108. SHA1 sha1 = SHA1.Create();
  109. byte[] saltedPassword = sha1.ComputeHash(rawSalted);
  110. // add the salt value to the salted hash
  111. byte[] dbPassword = new byte[saltedPassword.Length + saltValue.Length];
  112. saltedPassword.CopyTo(dbPassword, 0);
  113. saltValue.CopyTo(dbPassword, saltedPassword.Length);
  114. return dbPassword;
  115. }
  116. #endregion
  117. }
  118. }