private BsonValue ExplicitDecrypt( ClientEncryption clientEncryption, BsonBinaryData value, bool async) { BsonValue decryptedValue; if (async) { decryptedValue = clientEncryption .DecryptAsync( value, CancellationToken.None) .GetAwaiter() .GetResult(); } else { decryptedValue = clientEncryption.Decrypt( value, CancellationToken.None); } return(decryptedValue); }
protected override bool OnClientMessage(byte[] data) { switch (phase) { case Phase.Seed: if (data.Length != 4) { throw new SocketException("Invalid seed lenght.", this, data); } Seed = ByteConverter.LittleEndian.ToUInt32(data, 0); Trace.WriteLine(String.Format("Game seed sent by client: {0}", Seed.ToString("X")), "Communication"); SendToServer(data); phase = Phase.EncryptionDetection; return(true); case Phase.EncryptionDetection: CommunicationManager.ClientEncryption = DetectEncryption(data); Trace.WriteLine(String.Format("Client is using {0} encryption.", CommunicationManager.ClientEncryption), "Communication"); ClientEncryption = UOEncryption.Encryption.CreateServerGame(CommunicationManager.ClientEncryption, Seed); CommunicationManager.ServerEncryption = GetServerEncryption(CommunicationManager.ClientEncryption); Trace.WriteLine(String.Format("Server is using {0} encryption.", CommunicationManager.ServerEncryption), "Communication"); ServerEncryption = UOEncryption.Encryption.CreateClientGame(CommunicationManager.ServerEncryption, Seed); byte[] decrypted = ClientEncryption.Decrypt(data); SendToServer(decrypted); Core.OnClientMessage(decrypted, CallbackResult.Sent); phase = fixCharList ? Phase.CharacterList : Phase.Normal; return(true); case Phase.CharListSelect: if (data[0] != 0x5D) { throw new Exception("Invalid packet received from client. Did you selected properly character from list?"); } Trace.WriteLine("Character from fake list selected.", "Communication"); SendPendingData(); pendingData = null; phase = Phase.Normal; return(true); } return(base.OnClientMessage(data)); }
public void ClientSideExplicitEncryptionAndDecryptionTour() { RequireServer.Check().Supports(Feature.ClientSideEncryption); var localMasterKey = Convert.FromBase64String(LocalMasterKey); var kmsProviders = new Dictionary <string, IReadOnlyDictionary <string, object> >(); var localKey = new Dictionary <string, object> { { "key", localMasterKey } }; kmsProviders.Add("local", localKey); var keyVaultNamespace = CollectionNamespace.FromFullName("encryption.__keyVault"); var keyVaultClient = new MongoClient("mongodb://localhost"); var keyVaultDatabase = keyVaultClient.GetDatabase(keyVaultNamespace.DatabaseNamespace.DatabaseName); keyVaultDatabase.DropCollection(keyVaultNamespace.CollectionName); // Create the ClientEncryption instance var clientEncryptionSettings = new ClientEncryptionOptions( keyVaultClient, keyVaultNamespace, kmsProviders); using (var clientEncryption = new ClientEncryption(clientEncryptionSettings)) { var dataKeyId = clientEncryption.CreateDataKey( "local", new DataKeyOptions(), CancellationToken.None); var originalString = "123456789"; _output.WriteLine($"Original string {originalString}."); // Explicitly encrypt a field var encryptOptions = new EncryptOptions( EncryptionAlgorithm.AEAD_AES_256_CBC_HMAC_SHA_512_Deterministic.ToString(), keyId: dataKeyId); var encryptedFieldValue = clientEncryption.Encrypt( originalString, encryptOptions, CancellationToken.None); _output.WriteLine($"Encrypted value {encryptedFieldValue}."); // Explicitly decrypt the field var decryptedValue = clientEncryption.Decrypt(encryptedFieldValue, CancellationToken.None); _output.WriteLine($"Decrypted value {decryptedValue}."); } }
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)); }