using System.Net; using System.Text; using MySql.Data.MySqlClient; using Newtonsoft.Json; using System.Security.Claims; using System.IdentityModel.Tokens.Jwt; using Microsoft.IdentityModel.Tokens; using System.Security.Cryptography; namespace Server { public class Login { 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(ClaimTypes.Name, 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 run(MySqlConnection conn, HttpListenerRequest request, HttpListenerResponse response) { try { conn.Open(); // prepare SQL query MySqlCommand cmd = new MySqlCommand(); cmd.Connection = conn; cmd.CommandText = @"SELECT u.id,password FROM User u INNER JOIN Password p ON p.user=u.id WHERE mail=@mail"; var queryString = request.QueryString; string? mail = queryString["mail"]; string? password = queryString["password"]; cmd.Parameters.AddWithValue("@mail", mail); cmd.Parameters.AddWithValue("@password", password); // execute query and read results MySqlDataReader reader = cmd.ExecuteReader(); string? userId = ""; string? hashedPass = ""; string? jsonResponse; while (reader.Read()) { userId = Convert.ToString(reader["id"]); hashedPass = Convert.ToString(reader["password"]); } // check username if (string.IsNullOrEmpty(userId) && string.IsNullOrEmpty(hashedPass)) { throw new Exception("Error:Invalid Username or Password"); } //check password if (string.IsNullOrEmpty(password) || string.IsNullOrEmpty(hashedPass) || VerifyPassword(password, Convert.ToString(hashedPass))) { throw new Exception("Error:Invalid Username or Password"); } jsonResponse = JsonConvert.SerializeObject(GenerateToken(userId)); // prepare response byte[] buffer = Encoding.UTF8.GetBytes(jsonResponse); response.ContentType = "application/json"; response.ContentLength64 = buffer.Length; response.OutputStream.Write(buffer, 0, buffer.Length); } catch (Exception ex) { string errorMessage = $"Error: {ex.Message}"; byte[] buffer = Encoding.UTF8.GetBytes(errorMessage); response.ContentType = "text/plain"; response.ContentLength64 = buffer.Length; response.OutputStream.Write(buffer, 0, buffer.Length); } finally { // close db connection conn.Close(); } } } }