From 954c45ee8150b6604b29d74edb1b28e940a028eb Mon Sep 17 00:00:00 2001 From: Sean Date: Sun, 6 Apr 2025 18:21:49 -0400 Subject: [PATCH] Add user extensions and encryption modules. --- .../Extensions/UserExtensions.cs | 17 ++++++ .../MarketDataLib/Security/Encryption.cs | 52 +++++++++++++++++++ README.md | 10 +++- 3 files changed, 78 insertions(+), 1 deletion(-) create mode 100755 MarketData/MarketDataLib/Extensions/UserExtensions.cs create mode 100755 MarketData/MarketDataLib/Security/Encryption.cs diff --git a/MarketData/MarketDataLib/Extensions/UserExtensions.cs b/MarketData/MarketDataLib/Extensions/UserExtensions.cs new file mode 100755 index 0000000..a976aeb --- /dev/null +++ b/MarketData/MarketDataLib/Extensions/UserExtensions.cs @@ -0,0 +1,17 @@ +using MarketData.MarketDataModel.User; +using MarketData.Security; + +namespace MarketData.Extensions +{ + public static class UserExtensions + { + public static bool Verify(this User user, string password) + { + if(null == user || null == user.Username || null == user.Salt || null==user.Hash) + { + return false; + } + return Encryption.VerifyPassword(password, user.Salt, user.Hash); + } +} +} diff --git a/MarketData/MarketDataLib/Security/Encryption.cs b/MarketData/MarketDataLib/Security/Encryption.cs new file mode 100755 index 0000000..6a179f8 --- /dev/null +++ b/MarketData/MarketDataLib/Security/Encryption.cs @@ -0,0 +1,52 @@ +using System; +using System.Security.Cryptography; +using System.Text; + +namespace MarketData.Security +{ + public class Encryption + { + public static string HashPassword(string password) + { + using (SHA256 sha256 = SHA256.Create()) + { + byte[] bytes = Encoding.UTF8.GetBytes(password); + byte[] hashBytes = sha256.ComputeHash(bytes); + return Convert.ToBase64String(hashBytes); + } + } + + public static (string Salt, string Hash) HashPasswordWithSalt(string password) + { + using (RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider()) + { + byte[] salt = new byte[16]; + rng.GetBytes(salt); + using (SHA256 sha256 = SHA256.Create()) + { + byte[] passwordBytes = Encoding.UTF8.GetBytes(password); + byte[] saltedPassword = new byte[passwordBytes.Length + salt.Length]; + Buffer.BlockCopy(passwordBytes, 0, saltedPassword, 0, passwordBytes.Length); + Buffer.BlockCopy(salt, 0, saltedPassword, passwordBytes.Length, salt.Length); + byte[] hashBytes = sha256.ComputeHash(saltedPassword); + return (Convert.ToBase64String(salt), Convert.ToBase64String(hashBytes)); + } + } + } + + public static bool VerifyPassword(string inputPassword, string storedSalt, string storedHash) + { + byte[] salt = Convert.FromBase64String(storedSalt); + byte[] passwordBytes = Encoding.UTF8.GetBytes(inputPassword); + byte[] saltedPassword = new byte[passwordBytes.Length + salt.Length]; + Buffer.BlockCopy(passwordBytes, 0, saltedPassword, 0, passwordBytes.Length); + Buffer.BlockCopy(salt, 0, saltedPassword, passwordBytes.Length, salt.Length); + using (SHA256 sha256 = SHA256.Create()) + { + byte[] hashBytes = sha256.ComputeHash(saltedPassword); + string inputHash = Convert.ToBase64String(hashBytes); + return inputHash == storedHash; + } + } + } +} diff --git a/README.md b/README.md index 0430f5a..97234c3 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,15 @@ TO-DO 1) MariaDb online -2) MarketDataServer see dotnet add package Microsoft.AspNet.WebApi.SelfHost --version 5.3.0 +2) MarketDataServer + dotnet add package Microsoft.AspNet.WebApi.SelfHost --version 5.3.0 + dotnet add package System.ServiceModel.Primitives --version 4.0.0 + +Please use the Microsoft.AspNet.WebApi.OwinSelfHost package for new projects. +Microsoft.AspNet.WebApi.OwinSelfHost + + dotnet add package Microsoft.AspNet.WebApi.OwinSelfHost + 3) IPMonitor 4) Models