using Microsoft.AspNetCore.Cryptography.KeyDerivation;
using Microsoft.IdentityModel.Tokens;
using System;
using System.Collections.Generic;
using System.Drawing;
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;
}
///
/// 建立真隨機字串(CSPRNG),適用密碼、鹽
///
/// 長度
/// 要限制的字元串(長度需大於等於8),如果為null或者小於8,預設為"abcdefghijklmnopqrstuvwxyz1234567890"
///
public static string CreatSaltString(int stringLength, string key = null)
{
ReadOnlySpan 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();
}
///
/// 建立真隨機整數數字(CSPRNG),適用亂數、隨機編號
///
/// 最大值
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;
}
///
/// 建立真隨機整數數字(CSPRNG),適用亂數、隨機編號
///
/// 最小值
/// 最大值
public static int CreatSaltInt(int min, int max)
{
int value = CreatSaltInt(max - min) + min;
return value;
}
///
/// 剖析連接字串
///
///
///
public static Dictionary ParseConnectionString(string connectionString)
{
var d = new Dictionary();
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 圖片處理
///
/// 判斷圖片格式
///
/// 傳入Stream,注意請自行釋放
///
public static (bool, string) ImageValidateByStream(Stream stream)
{
int length = 20;
BinaryReader br = new BinaryReader(stream);
StringBuilder stringBuilder = new StringBuilder();
while (length > 0)
{
byte tempByte = br.ReadByte();
stringBuilder.Append(Convert.ToString(tempByte, 16));
stringBuilder.Append(",");
length--;
}
stream.Position = 0; //指針回歸為0
string fileheader = stringBuilder.ToString().ToUpper();
if (string.IsNullOrWhiteSpace(fileheader))
return (false, "");
if (fileheader.StartsWith("FF,D8,") || fileheader.StartsWith("42,4D,"))
return (true, "jpg");
if (fileheader.StartsWith("89,50,4E,47,D,A,1A,A,"))
return (true, "png");
if (fileheader.StartsWith("47,49,46,38,39,61,") || fileheader.StartsWith("47,49,46,38,37,61,"))
return (true, "gif");
//if (fileheader.StartsWith("4D,4D") || fileheader.StartsWith("49,49") || fileheader.StartsWith("46,4F,52,4D"))
// return (true, "tif");
return (false, "");
}
#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
}
}