using System.Net; using System.Text; using MySql.Data.MySqlClient; using System.Security.Cryptography; namespace Server { public class Register { public static string HashPassword(string password) { // Generate a salt using (var rng = new RNGCryptoServiceProvider()) { byte[] salt = new byte[16]; rng.GetBytes(salt); // Create a PBKDF2 instance to hash the password using (var pbkdf2 = new Rfc2898DeriveBytes(password, salt, 10000, HashAlgorithmName.SHA256)) { byte[] hash = pbkdf2.GetBytes(32); // Combine the salt and the hash together byte[] hashBytes = new byte[48]; // 16 (salt) + 32 (hash) Array.Copy(salt, 0, hashBytes, 0, 16); Array.Copy(hash, 0, hashBytes, 16, 32); // Return the final hash as a Base64 encoded string return Convert.ToBase64String(hashBytes); } } } public static void run(MySqlConnection conn, HttpListenerRequest request, HttpListenerResponse response) { try { // TODO: if one of the queries fails the others should be reverted in var queryString = request.QueryString; string? f_name = queryString["f_name"]; string? l_name = queryString["l_name"]; string? mail = queryString["mail"]; string? password = queryString["password"]; // validate parameters if (string.IsNullOrEmpty(f_name) || f_name.Length > 30 || f_name.Length < 2 || string.IsNullOrEmpty(l_name) || l_name.Length > 30 || l_name.Length < 2 || string.IsNullOrEmpty(mail) || mail.Length > 50 || mail.Length < 6 || string.IsNullOrEmpty(password) || password.Length > 30 || password.Length < 10) { throw new Exception("Wrong parameters"); } // open connection conn.Open(); // prepare SQL query MySqlCommand cmd = new MySqlCommand(); cmd.Connection = conn; // Insert into User cmd.CommandText = "INSERT INTO User(f_name,l_name,mail) VALUES(@f_name,@l_name,@mail)"; cmd.Parameters.AddWithValue("@f_name", f_name); cmd.Parameters.AddWithValue("@l_name", l_name); cmd.Parameters.AddWithValue("@mail", mail); cmd.ExecuteNonQuery(); // Get user ID cmd.CommandText = "SELECT id FROM User WHERE mail=@mail;"; MySqlDataReader reader = cmd.ExecuteReader(); reader.Read(); var id = reader["id"]; reader.Close(); // Insert into password cmd.CommandText = "INSERT INTO Password(user,password) VALUES(@id,@password)"; cmd.Parameters.AddWithValue("@password", HashPassword(password)); cmd.Parameters.AddWithValue("@id", id); cmd.ExecuteNonQuery(); response.StatusCode = (int)HttpStatusCode.OK; response.StatusDescription = "Status OK"; } 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(); } } } }