diff --git a/Account.cs b/Account.cs index e56e27a..95687f8 100644 --- a/Account.cs +++ b/Account.cs @@ -1,6 +1,12 @@ using System; +using System.Linq; +using System.Numerics; +using System.Text; using System.Collections.Generic; +using System.Security.Cryptography; using MySql.Data.MySqlClient; +using System.Globalization; +using MiscUtil.Conversion; namespace NightmareCoreWeb2 { @@ -11,6 +17,7 @@ namespace NightmareCoreWeb2 public string Username { get; set; } public string Email { get; set; } public string LastIP { get; set; } + public string Verifier {get; set;} public DateTime LastLogin { get; set; } public List Characters { get; set; } public List Access { get; set; } @@ -46,7 +53,7 @@ namespace NightmareCoreWeb2 MySqlConnection conn = new MySqlConnection(Program.connStr); conn.Open(); - string sql = "select id,username,email,last_ip,last_login from account where username=@username"; + string sql = "select id,username,email,last_ip,last_login,verifier from account where username=@username"; MySqlCommand cmd = new MySqlCommand(sql, conn); cmd.Parameters.AddWithValue("username", username); MySqlDataReader rdr = cmd.ExecuteReader(); @@ -60,6 +67,7 @@ namespace NightmareCoreWeb2 this.Email = rdr.GetString(2); this.LastIP = rdr.GetString(3); this.LastLogin = rdr.GetDateTime(4); + this.Verifier = rdr.GetString(5); } catch (Exception e) { @@ -116,10 +124,75 @@ namespace NightmareCoreWeb2 conn.Close(); } + public bool AuthenticateAccount(string password) + { + MySqlConnection conn = new MySqlConnection(Program.connStr); + conn.Open(); + string sql = "select salt,verifier from account where username=@username"; + MySqlCommand cmd = new MySqlCommand(sql, conn); + cmd.Parameters.AddWithValue("username", this.Username); + MySqlDataReader rdr = cmd.ExecuteReader(); + string salt = "", verifier = ""; + while (rdr.Read()) + { + try + { + salt = rdr.GetString(0); + verifier = rdr.GetString(1); + } + catch (Exception) { } + } + + return VerifySRP6Login(this.Username, password, Encoding.ASCII.GetBytes(salt), Encoding.ASCII.GetBytes(verifier)); + } + // https://gist.github.com/Rochet2/3bb0adaf6f3e9a9fbc78ba5ce9a43e09 + public static byte[] CalculateSRP6Verifier(string username, string password, byte[] salt_bytes) + { + // algorithm constants + BigInteger g = 7; + BigInteger N = BigInteger.Parse("894B645E89E1535BBDAD5B8B290650530801B18EBFBF5E8FAB3C82872A3E9BB7", NumberStyles.HexNumber); + + SHA1 sha1 = SHA1.Create(); + + // calculate first hash + byte[] login_bytes = Encoding.ASCII.GetBytes((username + ':' + password).ToUpper()); + byte[] h1_bytes = sha1.ComputeHash(login_bytes); + + // calculate second hash + byte[] h2_bytes = sha1.ComputeHash(salt_bytes.Concat(h1_bytes).ToArray()); + + // convert to integer (little-endian) + BigInteger h2 = new BigInteger(h2_bytes.Reverse().ToArray()); + Console.WriteLine(h2); + + // g^h2 mod N + BigInteger verifier = BigInteger.ModPow(g, h2, N); + + // convert back to a byte array (little-endian) + byte[] verifier_bytes = verifier.ToByteArray().Reverse().ToArray(); + + // pad to 32 bytes, remember that zeros go on the end in little-endian! + byte[] verifier_bytes_padded = new byte[Math.Max(32, verifier_bytes.Length)]; + Buffer.BlockCopy(verifier_bytes, 0, verifier_bytes_padded, 0, verifier_bytes.Length); + + // done! + return verifier_bytes_padded; + } + public static bool VerifySRP6Login(string username, string password, byte[] salt, byte[] verifier) + { + // re-calculate the verifier using the provided username + password and the stored salt + byte[] checkVerifier = CalculateSRP6Verifier(username, password, salt); + Console.WriteLine($"{Encoding.ASCII.GetString(verifier)}\n{Encoding.ASCII.GetString(checkVerifier)}"); + // compare it against the stored verifier + return verifier.SequenceEqual(checkVerifier); + } + } + public class AccountAccess { public int SecurityLevel { get; set; } public int RealmID { get; set; } } + } \ No newline at end of file diff --git a/Pages/Account.cshtml b/Pages/Account.cshtml index 6598fac..8879012 100644 --- a/Pages/Account.cshtml +++ b/Pages/Account.cshtml @@ -6,17 +6,32 @@ @if (string.IsNullOrEmpty(Model.AuthToken)) {
-
-
- - + +
+
+
Login
-
- - +
+ +
+ + +
+
+ + +
+ + @Html.AntiForgeryToken() + +
- +
+
+ + + } else { @@ -55,10 +70,14 @@

@ticket.Description


- Rename Character - Recustomize Character - Change Faction - Change Race + Rename + Character + Recustomize Character + Change + Faction + Change + Race