123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220 |
- using Microsoft.AspNetCore.Cryptography.KeyDerivation;
- using Microsoft.IdentityModel.Tokens;
- using System;
- using System.Collections.Generic;
- using System.Drawing;
- using System.Drawing.Drawing2D;
- using System.Drawing.Imaging;
- using System.IdentityModel.Tokens.Jwt;
- using System.IO;
- using System.Security.Claims;
- using System.Security.Cryptography;
- using System.Text;
- namespace TEAMModelOS.SDK.Extension
- {
- public class Utils
- {
- private static RNGCryptoServiceProvider _random = new RNGCryptoServiceProvider();
- public static string HashedPassword(string password, string salt)
- {
- byte[] hashBytes = KeyDerivation.Pbkdf2(
- password: password,
- salt: Encoding.UTF8.GetBytes(salt), //SHA1鹽(8-20字節),SHA256(32字節)
- prf: KeyDerivationPrf.HMACSHA1,
- iterationCount: 10000, //hash次數,越多次代表破解難度變高,但效能會差點
- numBytesRequested: 256 / 8 //指定得出結果長度
- );
- string hashText = BitConverter.ToString(hashBytes).Replace("-", string.Empty);
- return hashText;
- }
- /// <summary>
- /// 建立真隨機字串(CSPRNG),適用密碼、鹽
- /// </summary>
- /// <param name="stringLength">長度</param>
- /// <param name="key">要限制的字元串(長度需大於等於8),如果為null或者小於8,預設為"abcdefghijklmnopqrstuvwxyz1234567890"</param>
- /// <returns></returns>
- public static string CreatSaltString(int stringLength, string key = null)
- {
- ReadOnlySpan<char> span;
- if (key == null || key.Length < 8)
- span = "abcdefghijklmnopqrstuvwxyz1234567890";
- else
- span = key.AsSpan();
- int length = span.Length;
- StringBuilder randomString = new StringBuilder(length);
- for (int i = 0; i < stringLength; ++i)
- {
- randomString.Append(span[SetRandomSeeds(length)]);
- }
- return randomString.ToString();
- }
- /// <summary>
- /// 建立真隨機整數數字(CSPRNG),適用亂數、隨機編號
- /// </summary>
- /// <param name="max">最大值</param>
- public static int CreatSaltInt(int max)
- {
- var bytes = new byte[4];
- _random.GetBytes(bytes);
- int value = BitConverter.ToInt32(bytes, 0);
- value = value % (max + 1);
- if (value < 0) value = -value;
- return value;
- }
- /// <summary>
- /// 建立真隨機整數數字(CSPRNG),適用亂數、隨機編號
- /// </summary>
- /// <param name="min">最小值</param>
- /// <param name="max">最大值</param>
- public static int CreatSaltInt(int min, int max)
- {
- int value = CreatSaltInt(max - min) + min;
- return value;
- }
- /// <summary>
- /// 剖析連接字串
- /// </summary>
- /// <param name="connectionString"></param>
- /// <returns></returns>
- public static Dictionary<string, string> ParseConnectionString(string connectionString)
- {
- var d = new Dictionary<string, string>();
- foreach (var item in connectionString.Split(';', StringSplitOptions.RemoveEmptyEntries))
- {
- var a = item.IndexOf('=');
- d.Add(item.Substring(0, a), item.Substring(a + 1));
- }
- return d;
- }
- #region 圖片處理
- /// <summary>
- /// 判斷圖片格式
- /// </summary>
- /// <param name="stream">傳入Stream,注意請自行釋放</param>
- /// <returns></returns>
- public static (bool, string, int) ImageValidateByStream(Stream stream)
- {
- int length = 100000; //100 KB
- byte[] bytes = new byte[length];
- BinaryReader br = new BinaryReader(stream);
- StringBuilder stringBuilder = new StringBuilder();
- for (int i = 0; i < length; i++)
- {
- byte tempByte;
- try
- {
- tempByte = br.ReadByte();
- bytes[i] = tempByte;
- stringBuilder.Append(Convert.ToString(tempByte, 16));
- stringBuilder.Append(",");
- }
- catch
- {
- break; //如果發生檔尾損壞異常抱錯,直接跳離並結算stringBuilder
- }
- }
- stream.Position = 0; //指針回歸為0
- string fileheader = stringBuilder.ToString().ToUpper();
- if (string.IsNullOrWhiteSpace(fileheader))
- return (false, "", 0);
- if (fileheader.StartsWith("FF,D8,") || fileheader.StartsWith("42,4D,"))
- {
- int i = 2;
- int depth;
- while (true)
- {
- int marker = (bytes[i] & 0xff) << 8 | (bytes[i + 1] & 0xff);
- int size = (bytes[i + 2] & 0xff) << 8 | (bytes[i + 3] & 0xff);
- if (marker >= 0xffc0 && marker <= 0xffcf && marker != 0xffc4 && marker != 0xffc8)
- {
- depth = (bytes[i + 4] & 0xff) * (bytes[i + 9] & 0xff);
- break;
- }
- else i += size + 2;
- }
- return (true, "jpg", depth);
- }
- if (fileheader.StartsWith("89,50,4E,47,D,A,1A,A,"))
- {
- int depth = bytes[24] & 0xff;
- if ((bytes[25] & 0xff) == 2) depth *= 3;
- else if ((bytes[25] & 0xff) == 6) depth *= 4;
- return (true, "png", depth);
- }
- if (fileheader.StartsWith("47,49,46,38,39,61,") || fileheader.StartsWith("47,49,46,38,37,61,"))
- return (true, "gif", 0);
- if (fileheader.StartsWith("1,0,0,0,"))
- return (true, "emf", 0);
- if (fileheader.StartsWith("1,0,9,0,0,3"))
- return (true, "wmf", 0);
- //if (fileheader.StartsWith("4D,4D") || fileheader.StartsWith("49,49") || fileheader.StartsWith("46,4F,52,4D"))
- // return (true, "tif");
- return (false, "", 0);
- }
- /// <summary>
- /// 轉換EMF為PNG格式
- /// </summary>
- /// <param name="stream"></param>
- /// <returns></returns>
- public static string ConvertEMFtoPNG(Stream stream)
- {
- using var image = Image.FromStream(stream);
- //GDI+報錯,Azure Web App沙箱不支持GDI+部分權限
- //using var nbase64ms = new MemoryStream();
- //image.Save(nbase64ms, ImageFormat.Png); //保存為PNG格式
- //byte[] data = nbase64ms.ToArray();
- //string base64 = Convert.ToBase64String(data);
- //return base64;
- //Azure Web App沙箱不支持GDI+渲染部分EMF指令,可以出圖但會是空白
- var pngimage = new Bitmap(image.Width, image.Height);
- using (var graphics = Graphics.FromImage(pngimage))
- {
- graphics.CompositingQuality = CompositingQuality.HighSpeed;
- graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
- graphics.CompositingMode = CompositingMode.SourceCopy;
- graphics.DrawImage(image, 0, 0, image.Width, image.Height);
- using var nbase64ms = new MemoryStream();
- pngimage.Save(nbase64ms, ImageFormat.Png); //保存為PNG格式
- byte[] data = nbase64ms.ToArray();
- string base64 = Convert.ToBase64String(data);
- return base64;
- }
- }
- #endregion
- #region private
- private static int SetRandomSeeds(int length)
- {
- decimal maxValue = (decimal)long.MaxValue;
- byte[] array = new byte[8];
- _random.GetBytes(array);
- return (int)(Math.Abs(BitConverter.ToInt64(array, 0)) / maxValue * length);
- }
- #endregion
- }
- }
|