Utils.cs 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. using Microsoft.AspNetCore.Cryptography.KeyDerivation;
  2. using Microsoft.IdentityModel.Tokens;
  3. using System;
  4. using System.Collections.Generic;
  5. using System.Drawing;
  6. using System.Drawing.Imaging;
  7. using System.IdentityModel.Tokens.Jwt;
  8. using System.IO;
  9. using System.Security.Claims;
  10. using System.Security.Cryptography;
  11. using System.Text;
  12. namespace TEAMModelOS.SDK.Extension
  13. {
  14. public class Utils
  15. {
  16. private static RNGCryptoServiceProvider _random = new RNGCryptoServiceProvider();
  17. public static string HashedPassword(string password, string salt)
  18. {
  19. byte[] hashBytes = KeyDerivation.Pbkdf2(
  20. password: password,
  21. salt: Encoding.UTF8.GetBytes(salt), //SHA1鹽(8-20字節),SHA256(32字節)
  22. prf: KeyDerivationPrf.HMACSHA1,
  23. iterationCount: 10000, //hash次數,越多次代表破解難度變高,但效能會差點
  24. numBytesRequested: 256 / 8 //指定得出結果長度
  25. );
  26. string hashText = BitConverter.ToString(hashBytes).Replace("-", string.Empty);
  27. return hashText;
  28. }
  29. /// <summary>
  30. /// 建立真隨機字串(CSPRNG),適用密碼、鹽
  31. /// </summary>
  32. /// <param name="stringLength">長度</param>
  33. /// <param name="key">要限制的字元串(長度需大於等於8),如果為null或者小於8,預設為"abcdefghijklmnopqrstuvwxyz1234567890"</param>
  34. /// <returns></returns>
  35. public static string CreatSaltString(int stringLength, string key = null)
  36. {
  37. ReadOnlySpan<char> span;
  38. if (key == null || key.Length < 8)
  39. span = "abcdefghijklmnopqrstuvwxyz1234567890";
  40. else
  41. span = key.AsSpan();
  42. int length = span.Length;
  43. StringBuilder randomString = new StringBuilder(length);
  44. for (int i = 0; i < stringLength; ++i)
  45. {
  46. randomString.Append(span[SetRandomSeeds(length)]);
  47. }
  48. return randomString.ToString();
  49. }
  50. /// <summary>
  51. /// 建立真隨機整數數字(CSPRNG),適用亂數、隨機編號
  52. /// </summary>
  53. /// <param name="max">最大值</param>
  54. public static int CreatSaltInt(int max)
  55. {
  56. var bytes = new byte[4];
  57. _random.GetBytes(bytes);
  58. int value = BitConverter.ToInt32(bytes, 0);
  59. value = value % (max + 1);
  60. if (value < 0) value = -value;
  61. return value;
  62. }
  63. /// <summary>
  64. /// 建立真隨機整數數字(CSPRNG),適用亂數、隨機編號
  65. /// </summary>
  66. /// <param name="min">最小值</param>
  67. /// <param name="max">最大值</param>
  68. public static int CreatSaltInt(int min, int max)
  69. {
  70. int value = CreatSaltInt(max - min) + min;
  71. return value;
  72. }
  73. /// <summary>
  74. /// 剖析連接字串
  75. /// </summary>
  76. /// <param name="connectionString"></param>
  77. /// <returns></returns>
  78. public static Dictionary<string, string> ParseConnectionString(string connectionString)
  79. {
  80. var d = new Dictionary<string, string>();
  81. foreach (var item in connectionString.Split(';', StringSplitOptions.RemoveEmptyEntries))
  82. {
  83. var a = item.IndexOf('=');
  84. d.Add(item.Substring(0, a), item.Substring(a + 1));
  85. }
  86. return d;
  87. }
  88. #region 圖片處理
  89. /// <summary>
  90. /// 判斷圖片格式
  91. /// </summary>
  92. /// <param name="fileStream"></param>
  93. /// <returns></returns>
  94. public static (bool, ImageType) ImageValidateByStream(Stream fileStream)
  95. {
  96. using (BinaryReader br = new BinaryReader(fileStream))
  97. {
  98. int length = 20;
  99. StringBuilder stringBuilder = new StringBuilder();
  100. while (length > 0)
  101. {
  102. byte tempByte = br.ReadByte();
  103. stringBuilder.Append(Convert.ToString(tempByte, 16));
  104. stringBuilder.Append(",");
  105. length--;
  106. }
  107. string fileheader = stringBuilder.ToString().ToUpper();
  108. if (string.IsNullOrWhiteSpace(fileheader))
  109. return (false, ImageType.Error);
  110. if (fileheader.StartsWith("FF,D8,") || fileheader.StartsWith("42,4D,"))
  111. return (true, ImageType.JPEG);
  112. if (fileheader.StartsWith("89,50,4E,47,D,A,1A,A,"))
  113. return (true, ImageType.PNG);
  114. if (fileheader.StartsWith("47,49,46,38,39,61,") || fileheader.StartsWith("47,49,46,38,37,61,"))
  115. return (true, ImageType.GIF);
  116. if (fileheader.StartsWith("4D,4D") || fileheader.StartsWith("49,49") || fileheader.StartsWith("46,4F,52,4D"))
  117. return (true, ImageType.TIFF);
  118. return (false, ImageType.Empty);
  119. }
  120. }
  121. public enum ImageType
  122. {
  123. Error,
  124. Empty,
  125. JPEG,
  126. BMP,
  127. PNG,
  128. GIF,
  129. TIFF,
  130. IFF
  131. }
  132. #endregion
  133. #region private
  134. private static int SetRandomSeeds(int length)
  135. {
  136. decimal maxValue = (decimal)long.MaxValue;
  137. byte[] array = new byte[8];
  138. _random.GetBytes(array);
  139. return (int)(Math.Abs(BitConverter.ToInt64(array, 0)) / maxValue * length);
  140. }
  141. #endregion
  142. }
  143. }