using System.Net; using System.Text; using MySql.Data.MySqlClient; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using System.Security.Claims; using System.IdentityModel.Tokens.Jwt; using Microsoft.IdentityModel.Tokens; using System.Security.Cryptography; namespace Server { public class Login : Route { private static string secretKey = "stronk-key-much-sercret-much-more-stronk-stronk-key-much-sercret-much-more-stronk"; public static string GenerateToken(string user) { var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(secretKey)); var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256); var token = new JwtSecurityToken( issuer: "TimeLogServer", audience: "TimeLogWebsite", claims: new[] { new Claim("user", user) }, expires: DateTime.Now.AddHours(2), signingCredentials: creds ); return new JwtSecurityTokenHandler().WriteToken(token); } public static bool VerifyPassword(string enteredPassword, string storedHash) { byte[] hashBytes = Convert.FromBase64String(storedHash); // Extract the salt from the stored hash byte[] salt = new byte[16]; Array.Copy(hashBytes, 0, salt, 0, 16); // Hash the entered password with the stored salt using (var pbkdf2 = new Rfc2898DeriveBytes(enteredPassword, salt, 10000, HashAlgorithmName.SHA256)) { byte[] newHash = pbkdf2.GetBytes(32); // Compare the computed hash with the stored hash for (int i = 0; i < 32; i++) { if (newHash[i] != hashBytes[i + 16]) return false; } return true; } } public static void HandleRequest(HttpListenerRequest request, HttpListenerResponse response) { try { // extract data from body string body; using (StreamReader bodyReader = new StreamReader(request.InputStream, request.ContentEncoding)) { body = bodyReader.ReadToEnd(); } JObject jsonObject = JObject.Parse(body); string mail = jsonObject["mail"]?.ToString() ?? ""; string password = jsonObject["password"]?.ToString() ?? ""; // prepare SQL query MySqlCommand cmd = new MySqlCommand(); cmd.CommandText = @"SELECT u.id, password FROM User u INNER JOIN Password p ON p.user=u.id WHERE mail=@mail;"; cmd.Parameters.AddWithValue("@mail", mail); using (MySqlConnection conn = new MySqlConnection(connectionString)) { cmd.Connection = conn; conn.Open(); // execute query and read results MySqlDataReader reader = cmd.ExecuteReader(); string? userId = ""; string? hashedPass = ""; string? jsonResponse; while (reader.Read()) { userId = Convert.ToString(reader["id"]); hashedPass = reader.GetString("password"); } // check username if (string.IsNullOrEmpty(userId)) { throw new Exception("Invalid Username or Password"); } //check password if (string.IsNullOrEmpty(password) || string.IsNullOrEmpty(hashedPass) || !VerifyPassword(password, hashedPass)) { throw new Exception("Invalid Username or Password"); } jsonResponse = JsonConvert.SerializeObject(GenerateToken(userId)); // prepare response SendSuccess(response, jsonResponse); } } catch (Exception ex) { SendError(response, ex); } } } }