Utils.cs 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  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="stream">傳入Stream,注意請自行釋放</param>
  93. /// <returns></returns>
  94. public static (bool, string) ImageValidateByStream(Stream stream)
  95. {
  96. int length = 20;
  97. BinaryReader br = new BinaryReader(stream);
  98. StringBuilder stringBuilder = new StringBuilder();
  99. while (length > 0)
  100. {
  101. byte tempByte = br.ReadByte();
  102. stringBuilder.Append(Convert.ToString(tempByte, 16));
  103. stringBuilder.Append(",");
  104. length--;
  105. }
  106. stream.Position = 0; //指針回歸為0
  107. string fileheader = stringBuilder.ToString().ToUpper();
  108. if (string.IsNullOrWhiteSpace(fileheader))
  109. return (false, "");
  110. if (fileheader.StartsWith("FF,D8,") || fileheader.StartsWith("42,4D,"))
  111. return (true, "jpg");
  112. if (fileheader.StartsWith("89,50,4E,47,D,A,1A,A,"))
  113. return (true, "png");
  114. if (fileheader.StartsWith("47,49,46,38,39,61,") || fileheader.StartsWith("47,49,46,38,37,61,"))
  115. return (true, "gif");
  116. //if (fileheader.StartsWith("4D,4D") || fileheader.StartsWith("49,49") || fileheader.StartsWith("46,4F,52,4D"))
  117. // return (true, "tif");
  118. return (false, "");
  119. }
  120. #endregion
  121. #region private
  122. private static int SetRandomSeeds(int length)
  123. {
  124. decimal maxValue = (decimal)long.MaxValue;
  125. byte[] array = new byte[8];
  126. _random.GetBytes(array);
  127. return (int)(Math.Abs(BitConverter.ToInt64(array, 0)) / maxValue * length);
  128. }
  129. #endregion
  130. }
  131. }