public static Encryption CreateClientLogin(LoginEncryptionType type, uint seed, uint key1, uint key2) { IEncryptor encryptor; IDecryptor decryptor; switch (type) { case LoginEncryptionType.None: NoEncryption encryption = new NoEncryption(); encryptor = encryption; decryptor = encryption; break; case LoginEncryptionType.Old: case LoginEncryptionType.Rare: throw new Exception("Unsupported login encryption."); case LoginEncryptionType.New: encryptor = new LoginEncryption(seed, key1, key2); decryptor = new NoEncryption(); break; default: throw new Exception("Internal error."); } return new Encryption(encryptor, decryptor); }
public static Encryption CreateClientLogin(LoginEncryptionType type, uint seed, uint key1, uint key2) { IEncryptor encryptor; IDecryptor decryptor; switch (type) { case LoginEncryptionType.None: NoEncryption encryption = new NoEncryption(); encryptor = encryption; decryptor = encryption; break; case LoginEncryptionType.Old: case LoginEncryptionType.Rare: throw new Exception("Unsupported login encryption."); case LoginEncryptionType.New: encryptor = new LoginEncryption(seed, key1, key2); decryptor = new NoEncryption(); break; default: throw new Exception("Internal error."); } return(new Encryption(encryptor, decryptor)); }
public static EncryptionVersion FromLogin(LoginEncryptionType login) { switch (login) { case LoginEncryptionType.None: return(new EncryptionVersion()); case LoginEncryptionType.Old: return(new EncryptionVersion(1, 25, 35)); case LoginEncryptionType.Rare: return(new EncryptionVersion(1, 25, 36)); case LoginEncryptionType.New: return(new EncryptionVersion(1, 25, 37)); default: throw new Exception("Internal error."); } }
protected override bool OnClientMessage(byte[] data) { switch (phase) { case Phase.Seed: if (data.Length != 4) { throw new SocketException("Error while initializing LoginSocket. Invalid seed lenght.", this, data); } // Seed comes in little endian and encryption alghortm expects it in little endian, so i keep it as it is. Seed = ByteConverter.LittleEndian.ToUInt32(data, 0); CommunicationManager.LoginSeed = Seed; SendToServer(data); phase = Phase.Keys; return(true); case Phase.Keys: if (data.Length != 62) { throw new SocketException("Error while initializing LoginSocket. Invalid login packet lenght.", this, data); } // Detect and create client encryption uint key1; uint key2; LoginEncryptionType clientEnc = GetClientEncryption(data, out key1, out key2); ClientEncryption = Encryption.CreateServerLogin(clientEnc, Seed, key1, key2); // Read and create server encryption uint serverKey1; uint serverKey2; LoginEncryptionType serverEnc; int v = Int32.Parse(Core.LaunchData.ServerEncryption); switch (v) { case 0: serverKey1 = 0; serverKey2 = 0; serverEnc = LoginEncryptionType.None; Trace.WriteLine("Using no server encryption.", "Communication"); break; case 1: serverKey1 = key1; serverKey2 = key2; serverEnc = clientEnc; Trace.WriteLine(String.Format("Server key1: {1} key2: {2}", Seed.ToString("X"), serverKey1.ToString("X"), serverKey2.ToString("X")), "Communication"); break; default: try { serverKey1 = UInt32.Parse(Core.LaunchData.ServerKey1, System.Globalization.NumberStyles.HexNumber); serverKey2 = UInt32.Parse(Core.LaunchData.ServerKey2, System.Globalization.NumberStyles.HexNumber); serverEnc = LoginEncryptionType.New; } catch (Exception e) { throw new Exception("Error parsing server login keys.", e); } Trace.WriteLine(String.Format("Server key1: {1} key2: {2}", Seed.ToString("X"), serverKey1.ToString("X"), serverKey2.ToString("X")), "Communication"); break; } ServerEncryption = Encryption.CreateClientLogin(serverEnc, Seed, serverKey1, serverKey2); byte[] decrypted = ClientEncryption.Decrypt(data); // Save used account and password. They will be used to detect game encryprion. CommunicationManager.Username = ByteConverter.BigEndian.ToAsciiString(decrypted, 1, 30); CommunicationManager.Password = ByteConverter.BigEndian.ToAsciiString(decrypted, 31, 30); SendToServer(decrypted); // Zero password for security reasons for (int i = 31; i < 61; i++) { decrypted[i] = 0; } Core.OnClientMessage(decrypted, CallbackResult.Sent); phase = Phase.Normal; return(true); } return(base.OnClientMessage(data)); }