public static void Run() { Core.Initialize(); RegisterOpcodes(); loginSocket = Core.StartUDPReceiver(IPAddress.Parse("127.0.0.1"), 0, OnReceive); loginEndpoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 11000); var random = new RNGCryptoServiceProvider(); var randoma = new byte[20]; random.GetBytes(randoma); randoma[randoma.Length - 1] &= 0x7F; a = new BigInteger(randoma); PublicA = BigInteger.ModPow(g, a, N); var PublicABytes = PublicA.ToByteArray(); UDPTransmitter transmitter = UDPTransmitter.CreateObject(); transmitter.WriteUint16((UInt16)CMSG_AUTH_LOGON_CHALLENGE); //opcode transmitter.WriteUint16((UInt16)(9 + USERNAME.Length + PublicABytes.Length)); //packet_length transmitter.WriteUint8(BUILD_MAJOR); transmitter.WriteUint8(BUILD_MINOR); transmitter.WriteUint8(BUILD_REVISION); transmitter.WriteInt16(CLIENT_BUILD); transmitter.WriteUint16((UInt16)USERNAME.Length); transmitter.WriteFixedString(USERNAME); transmitter.WriteUint16((UInt16)PublicABytes.Length); transmitter.WriteFixedBlob(PublicABytes); transmitter.SendTo(loginSocket, loginEndpoint); }
private static void OnLogonChallengeOK(Session session, UDPReceiver data) { Console.WriteLine("[{0:yyyy-MM-dd HH\\:mm\\:ss}] [{1}:{2}] CMD_LOGON_CHALLENGE", DateTime.Now, session.RemoteEndPoint.Address, session.RemoteEndPoint.Port); UInt16 packet_size = data.ReadUint16(); UInt16 B_bytes_length = data.ReadUint16(); byte[] B_bytes = new byte[B_bytes_length]; PublicB = new BigInteger(data.ReadFixedBlob(ref B_bytes, B_bytes_length)); UInt16 S_bytes_length = data.ReadUint16(); byte[] S_bytes = new byte[S_bytes_length]; Salt = new BigInteger(data.ReadFixedBlob(ref S_bytes, S_bytes_length)); SHA256Managed sha = new SHA256Managed(); var u = new BigInteger(sha.ComputeHash(PublicA.ToByteArray().Concat(PublicB.ToByteArray()).ToArray()).Concat(new byte[] { 0 }).ToArray()); byte[] passwordHash = sha.ComputeHash(Encoding.ASCII.GetBytes(string.Format("{0}:{1}", USERNAME, PASSWORD.ToUpper()))); var x = new BigInteger(sha.ComputeHash(passwordHash.Concat(Salt.ToByteArray()).ToArray()).Concat(new byte[] { 0 }).ToArray()); var S = BigInteger.ModPow(PublicB - k * BigInteger.ModPow(g, x, N), (a + u * x), N); if (S < 0) { S = S + N; //C# incorrectly calculates the mod of negative numbers } var sessionkey = sha.ComputeHash(S.ToByteArray()); var M1 = sha.ComputeHash(PublicA.ToByteArray().Concat(PublicB.ToByteArray()).Concat(sessionkey).ToArray()); using (MemoryStream ms = new MemoryStream()) { using (BinaryWriter bw = new BinaryWriter(ms)) { bw.Write(M1, 0, M1.Length); } byte[] messageBody; messageBody = ms.ToArray(); using (MemoryStream ms1 = new MemoryStream()) { UDPTransmitter transmitter = UDPTransmitter.CreateObject(); transmitter.WriteUint16(CMSG_AUTH_LOGON_PROOF); transmitter.WriteUint16((UInt16)messageBody.Length); transmitter.WriteFixedBlob(messageBody); transmitter.SendTo(loginSocket, loginEndpoint); } } }