cleanup some old auth stuff
This commit is contained in:
parent
176c5e7197
commit
a4ae359df0
|
|
@ -1,7 +0,0 @@
|
|||
using System.Net;
|
||||
|
||||
namespace SimpleHttpServer;
|
||||
|
||||
public interface IAuthorizer {
|
||||
public abstract (bool auth, object? data) IsAuthenticated(HttpListenerContext contect);
|
||||
}
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
using System.Net;
|
||||
|
||||
namespace SimpleHttpServer.Internal;
|
||||
|
||||
public sealed class DefaultAuthorizer : IAuthorizer {
|
||||
public (bool auth, object? data) IsAuthenticated(HttpListenerContext contect) => (true, null);
|
||||
}
|
||||
|
|
@ -1,73 +1,73 @@
|
|||
using Newtonsoft.Json;
|
||||
using System.Collections;
|
||||
using System.Net;
|
||||
using System.Reflection;
|
||||
//using Newtonsoft.Json;
|
||||
//using System.Collections;
|
||||
//using System.Net;
|
||||
//using System.Reflection;
|
||||
|
||||
namespace SimpleHttpServer.Internal;
|
||||
//namespace SimpleHttpServer.Internal;
|
||||
|
||||
internal class HttpEndpointHandler {
|
||||
private static readonly DefaultAuthorizer defaultAuth = new();
|
||||
//internal class HttpEndpointHandler {
|
||||
// private static readonly DefaultAuthorizer defaultAuth = new();
|
||||
|
||||
private readonly IAuthorizer auth;
|
||||
private readonly MethodInfo handler;
|
||||
private readonly Dictionary<string, (int pindex, Type type, int pparamIdx)> @params;
|
||||
private readonly Func<Exception, HttpResponseBuilder> errorPageBuilder;
|
||||
// private readonly IAuthorizer auth;
|
||||
// private readonly MethodInfo handler;
|
||||
// private readonly Dictionary<string, (int pindex, Type type, int pparamIdx)> @params;
|
||||
// private readonly Func<Exception, HttpResponseBuilder> errorPageBuilder;
|
||||
|
||||
public HttpEndpointHandler() {
|
||||
auth = defaultAuth;
|
||||
}
|
||||
// public HttpEndpointHandler() {
|
||||
// auth = defaultAuth;
|
||||
// }
|
||||
|
||||
public HttpEndpointHandler(IAuthorizer auth) {
|
||||
// public HttpEndpointHandler(IAuthorizer auth) {
|
||||
|
||||
}
|
||||
// }
|
||||
|
||||
public virtual void Handle(HttpListenerContext ctx) {
|
||||
try {
|
||||
var (isAuth, authData) = auth.IsAuthenticated(ctx);
|
||||
if (!isAuth) {
|
||||
throw new HttpHandlingException(401, "Authorization required!");
|
||||
}
|
||||
// public virtual void Handle(HttpListenerContext ctx) {
|
||||
// try {
|
||||
// var (isAuth, authData) = auth.IsAuthenticated(ctx);
|
||||
// if (!isAuth) {
|
||||
// throw new HttpHandlingException(401, "Authorization required!");
|
||||
// }
|
||||
|
||||
// collect parameters
|
||||
var invokeParams = new object?[@params.Count + 1];
|
||||
var set = new BitArray(@params.Count);
|
||||
invokeParams[0] = ctx;
|
||||
// // collect parameters
|
||||
// var invokeParams = new object?[@params.Count + 1];
|
||||
// var set = new BitArray(@params.Count);
|
||||
// invokeParams[0] = ctx;
|
||||
|
||||
// read pparams
|
||||
// // read pparams
|
||||
|
||||
// read qparams
|
||||
var qst = ctx.Request.QueryString;
|
||||
foreach (var qelem in ctx.Request.QueryString.AllKeys) {
|
||||
if (@params.ContainsKey(qelem!)) {
|
||||
var (pindex, type, isPParam) = @params[qelem!];
|
||||
if (type == typeof(string)) {
|
||||
invokeParams[pindex] = ctx.Request.QueryString[qelem!];
|
||||
set.Set(pindex - 1, true);
|
||||
} else {
|
||||
var elem = JsonConvert.DeserializeObject(ctx.Request.QueryString[qelem!]!, type);
|
||||
if (elem != null) {
|
||||
invokeParams[pindex] = elem;
|
||||
set.Set(pindex - 1, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// // read qparams
|
||||
// var qst = ctx.Request.QueryString;
|
||||
// foreach (var qelem in ctx.Request.QueryString.AllKeys) {
|
||||
// if (@params.ContainsKey(qelem!)) {
|
||||
// var (pindex, type, isPParam) = @params[qelem!];
|
||||
// if (type == typeof(string)) {
|
||||
// invokeParams[pindex] = ctx.Request.QueryString[qelem!];
|
||||
// set.Set(pindex - 1, true);
|
||||
// } else {
|
||||
// var elem = JsonConvert.DeserializeObject(ctx.Request.QueryString[qelem!]!, type);
|
||||
// if (elem != null) {
|
||||
// invokeParams[pindex] = elem;
|
||||
// set.Set(pindex - 1, true);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// fill with defaults
|
||||
foreach (var p in @params) {
|
||||
if (!set.Get(p.Value.pindex)) {
|
||||
invokeParams[p.Value.pindex] = p.Value.type.IsValueType ? Activator.CreateInstance(p.Value.type) : null;
|
||||
}
|
||||
}
|
||||
// // fill with defaults
|
||||
// foreach (var p in @params) {
|
||||
// if (!set.Get(p.Value.pindex)) {
|
||||
// invokeParams[p.Value.pindex] = p.Value.type.IsValueType ? Activator.CreateInstance(p.Value.type) : null;
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
var builder = handler.Invoke(null, invokeParams) as HttpResponseBuilder;
|
||||
builder!.SendResponse(ctx.Response);
|
||||
} catch (Exception e) {
|
||||
if (e is TargetInvocationException tex) {
|
||||
e = tex.InnerException!;
|
||||
}
|
||||
errorPageBuilder(e).SendResponse(ctx.Response);
|
||||
}
|
||||
}
|
||||
}
|
||||
// var builder = handler.Invoke(null, invokeParams) as HttpResponseBuilder;
|
||||
// builder!.SendResponse(ctx.Response);
|
||||
// } catch (Exception e) {
|
||||
// if (e is TargetInvocationException tex) {
|
||||
// e = tex.InnerException!;
|
||||
// }
|
||||
// errorPageBuilder(e).SendResponse(ctx.Response);
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
|
|
|
|||
|
|
@ -1,245 +1,245 @@
|
|||
using Newtonsoft.Json;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
//using Newtonsoft.Json;
|
||||
//using System.Diagnostics.CodeAnalysis;
|
||||
//using System.Security.Cryptography;
|
||||
//using System.Text;
|
||||
|
||||
namespace SimpleHttpServer.Login;
|
||||
//namespace SimpleHttpServer.Login;
|
||||
|
||||
internal struct SerialLoginData {
|
||||
public string passwordSalt;
|
||||
public string extraDataSalt;
|
||||
public string pwd;
|
||||
public string extraData;
|
||||
//internal struct SerialLoginData {
|
||||
// public string passwordSalt;
|
||||
// public string extraDataSalt;
|
||||
// public string pwd;
|
||||
// public string extraData;
|
||||
|
||||
public LoginData ToPlainData() {
|
||||
return new LoginData {
|
||||
passwordSalt = Convert.FromBase64String(passwordSalt),
|
||||
extraDataSalt = Convert.FromBase64String(extraDataSalt)
|
||||
};
|
||||
}
|
||||
}
|
||||
// public LoginData ToPlainData() {
|
||||
// return new LoginData {
|
||||
// passwordSalt = Convert.FromBase64String(passwordSalt),
|
||||
// extraDataSalt = Convert.FromBase64String(extraDataSalt)
|
||||
// };
|
||||
// }
|
||||
//}
|
||||
|
||||
internal struct LoginData {
|
||||
public byte[] passwordSalt;
|
||||
public byte[] extraDataSalt;
|
||||
public byte[] passwordHash;
|
||||
public byte[] encryptedExtraData;
|
||||
//internal struct LoginData {
|
||||
// public byte[] passwordSalt;
|
||||
// public byte[] extraDataSalt;
|
||||
// public byte[] passwordHash;
|
||||
// public byte[] encryptedExtraData;
|
||||
|
||||
public SerialLoginData ToSerial() {
|
||||
return new SerialLoginData {
|
||||
passwordSalt = Convert.ToBase64String(passwordSalt),
|
||||
extraDataSalt = Convert.ToBase64String(extraDataSalt),
|
||||
pwd = Convert.ToBase64String(passwordHash),
|
||||
extraData = Convert.ToBase64String(encryptedExtraData)
|
||||
};
|
||||
}
|
||||
}
|
||||
// public SerialLoginData ToSerial() {
|
||||
// return new SerialLoginData {
|
||||
// passwordSalt = Convert.ToBase64String(passwordSalt),
|
||||
// extraDataSalt = Convert.ToBase64String(extraDataSalt),
|
||||
// pwd = Convert.ToBase64String(passwordHash),
|
||||
// extraData = Convert.ToBase64String(encryptedExtraData)
|
||||
// };
|
||||
// }
|
||||
//}
|
||||
|
||||
internal struct LoginDataProviderConfig {
|
||||
//internal struct LoginDataProviderConfig {
|
||||
|
||||
/// <summary>
|
||||
/// Size of the password salt and the extradata salt. So each salt will be of size <see cref="SALT_SIZE"/>.
|
||||
/// </summary>
|
||||
public int SALT_SIZE = 32;
|
||||
public int KEY_LENGTH = 256 / 8;
|
||||
public int PBKDF2_ITERATIONS = 600_000;
|
||||
// /// <summary>
|
||||
// /// Size of the password salt and the extradata salt. So each salt will be of size <see cref="SALT_SIZE"/>.
|
||||
// /// </summary>
|
||||
// public int SALT_SIZE = 32;
|
||||
// public int KEY_LENGTH = 256 / 8;
|
||||
// public int PBKDF2_ITERATIONS = 600_000;
|
||||
|
||||
public LoginDataProviderConfig() { }
|
||||
}
|
||||
// public LoginDataProviderConfig() { }
|
||||
//}
|
||||
|
||||
public class LoginProvider<TExtraData> {
|
||||
//public class LoginProvider<TExtraData> {
|
||||
|
||||
private static readonly Func<TExtraData, byte[]> JsonSerialize = t => Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(t));
|
||||
private static readonly Func<byte[], TExtraData> JsonDeserialize = b => JsonConvert.DeserializeObject<TExtraData>(Encoding.UTF8.GetString(b))!;
|
||||
// private static readonly Func<TExtraData, byte[]> JsonSerialize = t => Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(t));
|
||||
// private static readonly Func<byte[], TExtraData> JsonDeserialize = b => JsonConvert.DeserializeObject<TExtraData>(Encoding.UTF8.GetString(b))!;
|
||||
|
||||
[ThreadStatic]
|
||||
private static SHA256? _sha256PerThread;
|
||||
private static SHA256 Sha256PerThread { get => _sha256PerThread ??= SHA256.Create(); }
|
||||
// [ThreadStatic]
|
||||
// private static SHA256? _sha256PerThread;
|
||||
// private static SHA256 Sha256PerThread { get => _sha256PerThread ??= SHA256.Create(); }
|
||||
|
||||
private readonly LoginDataProviderConfig config;
|
||||
private readonly ReaderWriterLockSlim ldLock = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
|
||||
private readonly string ldPath;
|
||||
private readonly Dictionary<string, LoginData> loginDatas;
|
||||
// private readonly LoginDataProviderConfig config;
|
||||
// private readonly ReaderWriterLockSlim ldLock = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
|
||||
// private readonly string ldPath;
|
||||
// private readonly Dictionary<string, LoginData> loginDatas;
|
||||
|
||||
private Func<TExtraData, byte[]> DataSerializer = JsonSerialize;
|
||||
private Func<byte[], TExtraData> DataDeserializer = JsonDeserialize;
|
||||
public void SetDataSerializers(Func<TExtraData, byte[]> serializer, Func<byte[], TExtraData> deserializer) {
|
||||
DataSerializer = serializer ?? JsonSerialize;
|
||||
DataDeserializer = deserializer ?? JsonDeserialize;
|
||||
}
|
||||
// private Func<TExtraData, byte[]> DataSerializer = JsonSerialize;
|
||||
// private Func<byte[], TExtraData> DataDeserializer = JsonDeserialize;
|
||||
// public void SetDataSerializers(Func<TExtraData, byte[]> serializer, Func<byte[], TExtraData> deserializer) {
|
||||
// DataSerializer = serializer ?? JsonSerialize;
|
||||
// DataDeserializer = deserializer ?? JsonDeserialize;
|
||||
// }
|
||||
|
||||
|
||||
public LoginProvider(string ldPath, string confPath) {
|
||||
this.ldPath = ldPath;
|
||||
loginDatas = LoadLoginDatas(ldPath);
|
||||
config = LoadLoginProviderConfig(confPath);
|
||||
}
|
||||
// public LoginProvider(string ldPath, string confPath) {
|
||||
// this.ldPath = ldPath;
|
||||
// loginDatas = LoadLoginDatas(ldPath);
|
||||
// config = LoadLoginProviderConfig(confPath);
|
||||
// }
|
||||
|
||||
private static Dictionary<string, LoginData> LoadLoginDatas(string path) {
|
||||
Dictionary<string, SerialLoginData> tempData;
|
||||
if (!File.Exists(path)) {
|
||||
File.WriteAllText(path, "{}", Encoding.UTF8);
|
||||
tempData = new();
|
||||
} else {
|
||||
tempData = JsonConvert.DeserializeObject<Dictionary<string, SerialLoginData>>(File.ReadAllText(path))!;
|
||||
if (tempData == null) {
|
||||
throw new InvalidDataException($"could not read login data from file {path}");
|
||||
}
|
||||
}
|
||||
var ld = new Dictionary<string, LoginData>();
|
||||
foreach (var pair in tempData) {
|
||||
ld.Add(pair.Key, pair.Value.ToPlainData());
|
||||
}
|
||||
return ld;
|
||||
}
|
||||
// private static Dictionary<string, LoginData> LoadLoginDatas(string path) {
|
||||
// Dictionary<string, SerialLoginData> tempData;
|
||||
// if (!File.Exists(path)) {
|
||||
// File.WriteAllText(path, "{}", Encoding.UTF8);
|
||||
// tempData = new();
|
||||
// } else {
|
||||
// tempData = JsonConvert.DeserializeObject<Dictionary<string, SerialLoginData>>(File.ReadAllText(path))!;
|
||||
// if (tempData == null) {
|
||||
// throw new InvalidDataException($"could not read login data from file {path}");
|
||||
// }
|
||||
// }
|
||||
// var ld = new Dictionary<string, LoginData>();
|
||||
// foreach (var pair in tempData) {
|
||||
// ld.Add(pair.Key, pair.Value.ToPlainData());
|
||||
// }
|
||||
// return ld;
|
||||
// }
|
||||
|
||||
private void SaveLoginData() {
|
||||
var serial = new Dictionary<string, SerialLoginData>();
|
||||
ldLock.EnterWriteLock();
|
||||
try {
|
||||
foreach (var pair in loginDatas) {
|
||||
serial.Add(pair.Key, pair.Value.ToSerial());
|
||||
}
|
||||
} finally {
|
||||
ldLock.ExitWriteLock();
|
||||
}
|
||||
File.WriteAllText(ldPath, JsonConvert.SerializeObject(serial));
|
||||
}
|
||||
// private void SaveLoginData() {
|
||||
// var serial = new Dictionary<string, SerialLoginData>();
|
||||
// ldLock.EnterWriteLock();
|
||||
// try {
|
||||
// foreach (var pair in loginDatas) {
|
||||
// serial.Add(pair.Key, pair.Value.ToSerial());
|
||||
// }
|
||||
// } finally {
|
||||
// ldLock.ExitWriteLock();
|
||||
// }
|
||||
// File.WriteAllText(ldPath, JsonConvert.SerializeObject(serial));
|
||||
// }
|
||||
|
||||
private static LoginDataProviderConfig LoadLoginProviderConfig(string path) {
|
||||
if (!File.Exists(path)) {
|
||||
var conf = new LoginDataProviderConfig();
|
||||
File.WriteAllText(path, JsonConvert.SerializeObject(conf));
|
||||
return conf;
|
||||
}
|
||||
return JsonConvert.DeserializeObject<LoginDataProviderConfig>(File.ReadAllText(path));
|
||||
}
|
||||
// private static LoginDataProviderConfig LoadLoginProviderConfig(string path) {
|
||||
// if (!File.Exists(path)) {
|
||||
// var conf = new LoginDataProviderConfig();
|
||||
// File.WriteAllText(path, JsonConvert.SerializeObject(conf));
|
||||
// return conf;
|
||||
// }
|
||||
// return JsonConvert.DeserializeObject<LoginDataProviderConfig>(File.ReadAllText(path));
|
||||
// }
|
||||
|
||||
public bool AddUser(string username, string password, TExtraData additional) {
|
||||
ldLock.EnterWriteLock();
|
||||
try {
|
||||
if (loginDatas.ContainsKey(username)) {
|
||||
return false;
|
||||
}
|
||||
var passwordSalt = RandomNumberGenerator.GetBytes(config.SALT_SIZE);
|
||||
var extraDataSalt = RandomNumberGenerator.GetBytes(config.SALT_SIZE);
|
||||
LoginData ld = new LoginData() {
|
||||
passwordSalt = passwordSalt,
|
||||
extraDataSalt = extraDataSalt,
|
||||
passwordHash = ComputeSaltedSha256Hash(password, passwordSalt),
|
||||
encryptedExtraData = EncryptExtraData(password, extraDataSalt, additional),
|
||||
};
|
||||
loginDatas.Add(username, ld);
|
||||
SaveLoginData();
|
||||
} finally {
|
||||
ldLock.ExitWriteLock();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
// public bool AddUser(string username, string password, TExtraData additional) {
|
||||
// ldLock.EnterWriteLock();
|
||||
// try {
|
||||
// if (loginDatas.ContainsKey(username)) {
|
||||
// return false;
|
||||
// }
|
||||
// var passwordSalt = RandomNumberGenerator.GetBytes(config.SALT_SIZE);
|
||||
// var extraDataSalt = RandomNumberGenerator.GetBytes(config.SALT_SIZE);
|
||||
// LoginData ld = new LoginData() {
|
||||
// passwordSalt = passwordSalt,
|
||||
// extraDataSalt = extraDataSalt,
|
||||
// passwordHash = ComputeSaltedSha256Hash(password, passwordSalt),
|
||||
// encryptedExtraData = EncryptExtraData(password, extraDataSalt, additional),
|
||||
// };
|
||||
// loginDatas.Add(username, ld);
|
||||
// SaveLoginData();
|
||||
// } finally {
|
||||
// ldLock.ExitWriteLock();
|
||||
// }
|
||||
// return true;
|
||||
// }
|
||||
|
||||
public bool RemoveUser(string username) {
|
||||
ldLock.EnterWriteLock();
|
||||
try {
|
||||
var removed = loginDatas.Remove(username);
|
||||
if (removed) {
|
||||
SaveLoginData();
|
||||
}
|
||||
return removed;
|
||||
} finally {
|
||||
ldLock.ExitWriteLock();
|
||||
}
|
||||
}
|
||||
// public bool RemoveUser(string username) {
|
||||
// ldLock.EnterWriteLock();
|
||||
// try {
|
||||
// var removed = loginDatas.Remove(username);
|
||||
// if (removed) {
|
||||
// SaveLoginData();
|
||||
// }
|
||||
// return removed;
|
||||
// } finally {
|
||||
// ldLock.ExitWriteLock();
|
||||
// }
|
||||
// }
|
||||
|
||||
public bool ModifyUser(string username, string newPassword, TExtraData newExtraData) {
|
||||
ldLock.EnterWriteLock();
|
||||
try {
|
||||
if (!loginDatas.ContainsKey(username)) {
|
||||
return false;
|
||||
}
|
||||
loginDatas.Remove(username, out var data);
|
||||
data.passwordHash = ComputeSaltedSha256Hash(newPassword, data.passwordSalt);
|
||||
data.encryptedExtraData = EncryptExtraData(newPassword, data.extraDataSalt, newExtraData);
|
||||
loginDatas.Add(username, data);
|
||||
SaveLoginData();
|
||||
} finally {
|
||||
ldLock.ExitWriteLock();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
// public bool ModifyUser(string username, string newPassword, TExtraData newExtraData) {
|
||||
// ldLock.EnterWriteLock();
|
||||
// try {
|
||||
// if (!loginDatas.ContainsKey(username)) {
|
||||
// return false;
|
||||
// }
|
||||
// loginDatas.Remove(username, out var data);
|
||||
// data.passwordHash = ComputeSaltedSha256Hash(newPassword, data.passwordSalt);
|
||||
// data.encryptedExtraData = EncryptExtraData(newPassword, data.extraDataSalt, newExtraData);
|
||||
// loginDatas.Add(username, data);
|
||||
// SaveLoginData();
|
||||
// } finally {
|
||||
// ldLock.ExitWriteLock();
|
||||
// }
|
||||
// return true;
|
||||
// }
|
||||
|
||||
public bool TryAuthenticate(string username, string password, [MaybeNullWhen(false)] out TExtraData extraData) {
|
||||
LoginData data;
|
||||
ldLock.EnterReadLock();
|
||||
try {
|
||||
if (!loginDatas.TryGetValue(username, out data)) {
|
||||
extraData = default;
|
||||
return false;
|
||||
}
|
||||
} finally {
|
||||
ldLock.ExitReadLock();
|
||||
}
|
||||
var hash = ComputeSaltedSha256Hash(password, data.passwordSalt);
|
||||
if (!hash.SequenceEqual(data.passwordHash)) {
|
||||
extraData = default;
|
||||
return false;
|
||||
}
|
||||
extraData = DecryptExtraData(password, data.extraDataSalt, data.encryptedExtraData);
|
||||
return true;
|
||||
}
|
||||
// public bool TryAuthenticate(string username, string password, [MaybeNullWhen(false)] out TExtraData extraData) {
|
||||
// LoginData data;
|
||||
// ldLock.EnterReadLock();
|
||||
// try {
|
||||
// if (!loginDatas.TryGetValue(username, out data)) {
|
||||
// extraData = default;
|
||||
// return false;
|
||||
// }
|
||||
// } finally {
|
||||
// ldLock.ExitReadLock();
|
||||
// }
|
||||
// var hash = ComputeSaltedSha256Hash(password, data.passwordSalt);
|
||||
// if (!hash.SequenceEqual(data.passwordHash)) {
|
||||
// extraData = default;
|
||||
// return false;
|
||||
// }
|
||||
// extraData = DecryptExtraData(password, data.extraDataSalt, data.encryptedExtraData);
|
||||
// return true;
|
||||
// }
|
||||
|
||||
/// <summary>
|
||||
/// Threadsafe as the SHA256 instance (<see cref="Sha256PerThread"/>) is per thread.
|
||||
/// </summary>
|
||||
/// <param name="data"></param>
|
||||
/// <param name="salt"></param>
|
||||
/// <returns></returns>
|
||||
private static byte[] ComputeSaltedSha256Hash(string data, byte[] salt) {
|
||||
var dataBytes = Encoding.UTF8.GetBytes(data);
|
||||
var buf = new byte[data.Length + salt.Length];
|
||||
Buffer.BlockCopy(dataBytes, 0, buf, 0, dataBytes.Length);
|
||||
Buffer.BlockCopy(salt, 0, buf, dataBytes.Length, salt.Length);
|
||||
return Sha256PerThread.ComputeHash(buf);
|
||||
}
|
||||
// /// <summary>
|
||||
// /// Threadsafe as the SHA256 instance (<see cref="Sha256PerThread"/>) is per thread.
|
||||
// /// </summary>
|
||||
// /// <param name="data"></param>
|
||||
// /// <param name="salt"></param>
|
||||
// /// <returns></returns>
|
||||
// private static byte[] ComputeSaltedSha256Hash(string data, byte[] salt) {
|
||||
// var dataBytes = Encoding.UTF8.GetBytes(data);
|
||||
// var buf = new byte[data.Length + salt.Length];
|
||||
// Buffer.BlockCopy(dataBytes, 0, buf, 0, dataBytes.Length);
|
||||
// Buffer.BlockCopy(salt, 0, buf, dataBytes.Length, salt.Length);
|
||||
// return Sha256PerThread.ComputeHash(buf);
|
||||
// }
|
||||
|
||||
private byte[] EncryptExtraData(string pwd, byte[] salt, TExtraData extraData) {
|
||||
var pbkdf2 = new Rfc2898DeriveBytes(Encoding.UTF8.GetBytes(pwd), salt, config.PBKDF2_ITERATIONS, HashAlgorithmName.SHA256);
|
||||
var key = pbkdf2.GetBytes(config.KEY_LENGTH / 8);
|
||||
// private byte[] EncryptExtraData(string pwd, byte[] salt, TExtraData extraData) {
|
||||
// var pbkdf2 = new Rfc2898DeriveBytes(Encoding.UTF8.GetBytes(pwd), salt, config.PBKDF2_ITERATIONS, HashAlgorithmName.SHA256);
|
||||
// var key = pbkdf2.GetBytes(config.KEY_LENGTH / 8);
|
||||
|
||||
var plainBytes = DataSerializer(extraData);
|
||||
using var aes = Aes.Create();
|
||||
aes.KeySize = config.KEY_LENGTH;
|
||||
aes.Key = key;
|
||||
aes.Mode = CipherMode.CBC;
|
||||
aes.Padding = PaddingMode.PKCS7;
|
||||
ICryptoTransform encryptor = aes.CreateEncryptor(aes.Key, aes.IV);
|
||||
byte[] cipherBytes = encryptor.TransformFinalBlock(plainBytes, 0, plainBytes.Length);
|
||||
// var plainBytes = DataSerializer(extraData);
|
||||
// using var aes = Aes.Create();
|
||||
// aes.KeySize = config.KEY_LENGTH;
|
||||
// aes.Key = key;
|
||||
// aes.Mode = CipherMode.CBC;
|
||||
// aes.Padding = PaddingMode.PKCS7;
|
||||
// ICryptoTransform encryptor = aes.CreateEncryptor(aes.Key, aes.IV);
|
||||
// byte[] cipherBytes = encryptor.TransformFinalBlock(plainBytes, 0, plainBytes.Length);
|
||||
|
||||
var encryptedBytes = new byte[aes.IV.Length + cipherBytes.Length];
|
||||
Array.Copy(aes.IV, 0, encryptedBytes, 0, aes.IV.Length);
|
||||
Array.Copy(cipherBytes, 0, encryptedBytes, aes.IV.Length, cipherBytes.Length);
|
||||
// var encryptedBytes = new byte[aes.IV.Length + cipherBytes.Length];
|
||||
// Array.Copy(aes.IV, 0, encryptedBytes, 0, aes.IV.Length);
|
||||
// Array.Copy(cipherBytes, 0, encryptedBytes, aes.IV.Length, cipherBytes.Length);
|
||||
|
||||
return encryptedBytes;
|
||||
}
|
||||
// return encryptedBytes;
|
||||
// }
|
||||
|
||||
private TExtraData DecryptExtraData(string pwd, byte[] salt, byte[] encryptedData) {
|
||||
var pbkdf2 = new Rfc2898DeriveBytes(Encoding.UTF8.GetBytes(pwd), salt, config.PBKDF2_ITERATIONS, HashAlgorithmName.SHA256);
|
||||
var key = pbkdf2.GetBytes(config.KEY_LENGTH / 8);
|
||||
// private TExtraData DecryptExtraData(string pwd, byte[] salt, byte[] encryptedData) {
|
||||
// var pbkdf2 = new Rfc2898DeriveBytes(Encoding.UTF8.GetBytes(pwd), salt, config.PBKDF2_ITERATIONS, HashAlgorithmName.SHA256);
|
||||
// var key = pbkdf2.GetBytes(config.KEY_LENGTH / 8);
|
||||
|
||||
using var aes = Aes.Create();
|
||||
aes.KeySize = config.KEY_LENGTH;
|
||||
aes.Key = key;
|
||||
aes.Mode = CipherMode.CBC;
|
||||
aes.Padding = PaddingMode.PKCS7;
|
||||
var iv = new byte[aes.BlockSize / 8];
|
||||
var cipherBytes = new byte[encryptedData.Length - iv.Length];
|
||||
// using var aes = Aes.Create();
|
||||
// aes.KeySize = config.KEY_LENGTH;
|
||||
// aes.Key = key;
|
||||
// aes.Mode = CipherMode.CBC;
|
||||
// aes.Padding = PaddingMode.PKCS7;
|
||||
// var iv = new byte[aes.BlockSize / 8];
|
||||
// var cipherBytes = new byte[encryptedData.Length - iv.Length];
|
||||
|
||||
Array.Copy(encryptedData, 0, iv, 0, iv.Length);
|
||||
Array.Copy(encryptedData, iv.Length, cipherBytes, 0, cipherBytes.Length);
|
||||
// Array.Copy(encryptedData, 0, iv, 0, iv.Length);
|
||||
// Array.Copy(encryptedData, iv.Length, cipherBytes, 0, cipherBytes.Length);
|
||||
|
||||
aes.IV = iv;
|
||||
ICryptoTransform decryptor = aes.CreateDecryptor(aes.Key, aes.IV);
|
||||
byte[] plainBytes = decryptor.TransformFinalBlock(cipherBytes, 0, cipherBytes.Length);
|
||||
// aes.IV = iv;
|
||||
// ICryptoTransform decryptor = aes.CreateDecryptor(aes.Key, aes.IV);
|
||||
// byte[] plainBytes = decryptor.TransformFinalBlock(cipherBytes, 0, cipherBytes.Length);
|
||||
|
||||
return DataDeserializer(plainBytes);
|
||||
}
|
||||
}
|
||||
// return DataDeserializer(plainBytes);
|
||||
// }
|
||||
//}
|
||||
|
|
|
|||
|
|
@ -19,9 +19,11 @@ public class RequestContext : IDisposable {
|
|||
/// </summary>
|
||||
public TextWriter RespWriter => respWriter ??= TextWriter.Synchronized(new StreamWriter(ListenerContext.Response.OutputStream) { NewLine = "\n" });
|
||||
|
||||
#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
|
||||
public RequestContext(HttpListenerContext listenerContext) {
|
||||
ListenerContext = listenerContext;
|
||||
}
|
||||
#pragma warning restore CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
|
||||
|
||||
public async Task WriteLineToRespAsync(string resp) => await RespWriter.WriteLineAsync(resp);
|
||||
public async Task WriteToRespAsync(string resp) => await RespWriter.WriteAsync(resp);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user