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);
        }
        public void CheckServerEncryption_RM()
        {
            GenerateClientSessionKeys(out _, out var encryptedSessionKeys);
            List <byte[]> decryptedSessionKeys = new List <byte[]>();

            foreach (string key in encryptedSessionKeys)
            {
                decryptedSessionKeys.Add(ServerEncryption.RsaDecryptCipher(key));
            }

            Assert.That(decryptedSessionKeys.Count > 0);
            for (int i = 0; i < decryptedSessionKeys.Count; i++)
            {
                string plainText = GenerateRandomString(36);
                Assert.That(plainText.Length == 36);

                // Encrypt and prepare the message.
                string cipher  = ServerEncryption.EncryptPlainText(plainText, decryptedSessionKeys[i], out string initialisationVector).ToHexString();
                string message = $"{initialisationVector}{cipher}";

                // Decrypt the message [ClientDecryption_RM]
                byte[] initialisationVectorBytes = ClientEncryption.ParseIvFromMessage(message);
                byte[] cipherBytes = ClientEncryption.ParseCipherFromMessage(message);
                string decipher    = ClientEncryption.DecryptCipher(cipherBytes, decryptedSessionKeys[i], initialisationVectorBytes);

                Assert.AreEqual(plainText, decipher);
            }
        }
        private BsonBinaryData ExplicitEncrypt(
            ClientEncryption clientEncryption,
            EncryptOptions encryptOptions,
            BsonValue value,
            bool async)
        {
            BsonBinaryData encryptedValue;

            if (async)
            {
                encryptedValue = clientEncryption
                                 .EncryptAsync(
                    value,
                    encryptOptions,
                    CancellationToken.None)
                                 .GetAwaiter()
                                 .GetResult();
            }
            else
            {
                encryptedValue = clientEncryption.Encrypt(
                    value,
                    encryptOptions,
                    CancellationToken.None);
            }

            return(encryptedValue);
        }
        /// <summary>
        /// Generates various session key states for the unit tests.
        /// </summary>
        private static void GenerateClientSessionKeys(out List <string> unencryptedSessionKeys, out List <string> encryptedSessionKeys)
        {
            unencryptedSessionKeys = new List <string>();
            encryptedSessionKeys   = new List <string>();

            for (int i = 0; i < 1_000; i++)
            {
                unencryptedSessionKeys.Add(ClientEncryption.SessionKey);
                encryptedSessionKeys.Add(ClientEncryption.RsaEncryptCipher(true).ToHexString());
            }
        }
示例#5
0
        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}.");
            }
        }
示例#7
0
        private EncryptionSetup GetEncryptionSetup(ClientEncryption encryption)
        {
            switch (encryption)
            {
            case ClientEncryption.add:
                return(EncryptionSetup.EncryptedServer);

            case ClientEncryption.auto:
                return(EncryptionSetup.Autodetect);

            case ClientEncryption.remove:
                return(EncryptionSetup.EncryptedClient);

            default:
                throw new NotImplementedException($"Unknown ClientEncryption value '{encryption}'");
            }
        }
示例#8
0
文件: Program.cs 项目: Bigsby/PoC
        static void Main(string[] args)
        {
            var ci = new ClientIdentity
            {
                HostName   = "host",
                MACAddress = "mac",
                MachineID  = "id"
            };

            var encrypted = ClientEncryption.EncryptIdentity(ci);

            var encryptedString = BitConverter.ToString(encrypted).Replace("-", string.Empty);

            var decrypted = ClientEncryption.DecryptIdentity(StringToByteArray("3266B2AA6097FD72E8D098253DFA34D44D36B996E6E63BBE5FB5D19C42759C5B361202AA482C74693442A25168194D54878A7C923C146B640152D14DE5C08E4F661E1AD7D12B32644FFE4AA41BABE0A5"));
            //var decrypted = ClientEncryption.DecryptIdentity(StringToByteArray("6AEB5D337B939B57318F7B9D7EB58D780510DEBF3F4DDF4F1C4700765292846827AA82F1EA8184FFD4C4DA2E6A897B2240A2E4C6274322D272B399DBD71CF112"));
            var stop = "here";
        }
 private Guid CreateDataKey(
     ClientEncryption clientEncryption,
     string kmsProvider,
     DataKeyOptions dataKeyOptions,
     bool async)
 {
     if (async)
     {
         return(clientEncryption
                .CreateDataKeyAsync(kmsProvider, dataKeyOptions, CancellationToken.None)
                .GetAwaiter()
                .GetResult());
     }
     else
     {
         return(clientEncryption.CreateDataKey(kmsProvider, dataKeyOptions, CancellationToken.None));
     }
 }
示例#10
0
        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));
        }
        // public void ClientSideEncryptionAutoEncryptionSettingsTour()
        public static void Main(string[] args)
        {
            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 keyVaultDB        = "keyVault";
            var keystore          = "__keystore";
            var keyVaultNamespace = CollectionNamespace.FromFullName($"{keyVaultDB}.{keystore}");

            var keyVaultMongoClient      = new MongoClient();
            var clientEncryptionSettings = new ClientEncryptionOptions(
                keyVaultMongoClient,
                keyVaultNamespace,
                kmsProviders);
            var clientEncryption = new ClientEncryption(clientEncryptionSettings);

            keyVaultMongoClient.GetDatabase(keyVaultDB).DropCollection(keystore);

            var altKeyName      = new[] { "csharpDataKey01" };
            var dataKeyOptions  = new DataKeyOptions(alternateKeyNames: altKeyName);
            var dataKeyId       = clientEncryption.CreateDataKey("local", dataKeyOptions, CancellationToken.None);
            var base64DataKeyId = Convert.ToBase64String(GuidConverter.ToBytes(dataKeyId, GuidRepresentation.Standard));

            clientEncryption.Dispose();

            var collectionNamespace = CollectionNamespace.FromFullName("test.coll");

            var schemaMap = $@"{{
                properties: {{
                    SSN: {{
                        encrypt: {{
                            keyId: [{{
                                '$binary' : {{
                                    'base64' : '{base64DataKeyId}',
                                    'subType' : '04'
                                }}
                            }}],
                        bsonType: 'string',
                        algorithm: 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'
                        }}
                    }}
                }},
                'bsonType': 'object'
            }}";
            var autoEncryptionSettings = new AutoEncryptionOptions(
                keyVaultNamespace,
                kmsProviders,
                schemaMap: new Dictionary <string, BsonDocument>()
            {
                { collectionNamespace.ToString(), BsonDocument.Parse(schemaMap) }
            });
            var clientSettings = new MongoClientSettings
            {
                AutoEncryptionOptions = autoEncryptionSettings
            };
            var client   = new MongoClient(clientSettings);
            var database = client.GetDatabase("test");

            database.DropCollection("coll");

            var collection = database.GetCollection <BsonDocument>("coll");

            collection.InsertOne(new BsonDocument("SSN", "123456789"));

            var result = collection.Find(FilterDefinition <BsonDocument> .Empty).First();

            Console.WriteLine(result.ToJson());
        }
        public void ClientSideExplicitEncryptionAndAutoDecryptionTour()
        {
            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 collectionNamespace   = CollectionNamespace.FromFullName("test.coll");
            var autoEncryptionOptions = new AutoEncryptionOptions(
                keyVaultNamespace,
                kmsProviders,
                bypassAutoEncryption: true);
            var clientSettings = MongoClientSettings.FromConnectionString("mongodb://localhost");

            clientSettings.AutoEncryptionOptions = autoEncryptionOptions;
            var mongoClient = new MongoClient(clientSettings);
            var database    = mongoClient.GetDatabase(collectionNamespace.DatabaseNamespace.DatabaseName);

            database.DropCollection(collectionNamespace.CollectionName);
            var collection = database.GetCollection <BsonDocument>(collectionNamespace.CollectionName);

            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}.");

                collection.InsertOne(new BsonDocument("encryptedField", encryptedFieldValue));

                // Automatically decrypts the encrypted field.
                var decryptedValue = collection.Find(FilterDefinition <BsonDocument> .Empty).First();
                _output.WriteLine($"Decrypted document {decryptedValue.ToJson()}.");
            }
        }
 public static ExplicitEncryptionLibMongoCryptController _libMongoCryptController(this ClientEncryption clientEncryption)
 {
     return((ExplicitEncryptionLibMongoCryptController)Reflector.GetFieldValue(clientEncryption, nameof(_libMongoCryptController)));
 }
示例#14
0
        public static void Main(string[] args)
        {
            // T0
            // -- CLIENT --
            // Simulating a client-server relationship, the first step required is for the client to
            // generate a session key and encrypt it by virtue of the server's public key.
            // (Because the encryption libraries are static, this first step is automatically completed.)
            string sessionKey = ClientEncryption.RsaEncryptCipher().ToHexString();

            Console.WriteLine($"Client session key is: {sessionKey}");
            // At this point, the client sends this session key to the server.
            // -- END CLIENT --

            // T1
            // -- SERVER --
            // Once the server receives this session key, it must decrypt it by virtue of its private key.
            // Now actual messages can be sent.
            byte[] decryptedSessionKey = ServerEncryption.RsaDecryptCipher(sessionKey);
            Console.WriteLine($"Client session key length is: {decryptedSessionKey.Length}");
            // -- END SERVER --

            while (true)
            {
                // T2
                // At this stage, your program will send whatever information to the server or client.
                Console.WriteLine("Please enter some plain text: ");
                string plainText = Console.ReadLine();

                // T3
                // -- CLIENT --
                // Now the session key can be itself used for encryption.
                // Hex string is convenient for sending data because its characters are wide-spread.
                string initialisationVector = ClientEncryption.InitialisationVector;
                Console.WriteLine($"The current initialisation vector is: {initialisationVector}");

                // Encrypt the plain text.
                string cipher = ClientEncryption.EncryptPlainText(plainText, sessionKey.ToByteArray()).ToHexString();
                Console.WriteLine($"Your plain text ({plainText}) encrypted is: {cipher}");

                // Then send the cipher to the server.
                // Remember to send the initialisation vector, if using it, along with the message, like so:
                string message = $"{initialisationVector}{cipher}";
                Console.WriteLine($"The complete message (IV and cipher) is: {message}");
                // -- END CLIENT --

                // T4
                // -- SERVER --
                // The server then receives an encrypted (hex) string. However, it first needs to organise the
                // information before decrypting it, by discerning the IV and cipher (i.e., the actual message).
                // Of course, this step is not necessary if you decide not to utilise initialisation vectors.
                byte[] initialisationVectorBytes = ServerEncryption.ParseIvFromMessage(message);
                Console.WriteLine($"The length of the initialisation vector is: {initialisationVectorBytes.Length}");
                byte[] decipherBytes = ServerEncryption.ParseCipherFromMessage(message);
                Console.WriteLine($"The length of the (de)cipher is: {decipherBytes.Length}");

                // All that is remaining to do is to decrypt the cipher.
                string decipher = ServerEncryption.DecryptCipher(decipherBytes, decryptedSessionKey, initialisationVectorBytes);
                Console.WriteLine($"The deciphered message is: {decipher}");
                // Decryption complete.
                // -- END SERVER --
            }
        }
示例#15
0
        public void ClientSideEncryptionAutoEncryptionSettingsTour()
        {
            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("admin.datakeys");
            var keyVaultMongoClient      = new MongoClient();
            var clientEncryptionSettings = new ClientEncryptionOptions(
                keyVaultMongoClient,
                keyVaultNamespace,
                kmsProviders);

            var clientEncryption = new ClientEncryption(clientEncryptionSettings);
            var dataKeyId        = clientEncryption.CreateDataKey("local", new DataKeyOptions(), CancellationToken.None);
            var base64DataKeyId  = Convert.ToBase64String(GuidConverter.ToBytes(dataKeyId, GuidRepresentation.Standard));

            clientEncryption.Dispose();

            var collectionNamespace = CollectionNamespace.FromFullName("test.coll");

            var schemaMap = $@"{{
                properties: {{
                    encryptedField: {{
                        encrypt: {{
                            keyId: [{{
                                '$binary' : {{
                                    'base64' : '{base64DataKeyId}',
                                    'subType' : '04'
                                }}
                            }}],
                        bsonType: 'string',
                        algorithm: 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'
                        }}
                    }}
                }},
                'bsonType': 'object'
            }}";
            var autoEncryptionSettings = new AutoEncryptionOptions(
                keyVaultNamespace,
                kmsProviders,
                schemaMap: new Dictionary <string, BsonDocument>()
            {
                { collectionNamespace.ToString(), BsonDocument.Parse(schemaMap) }
            });
            var clientSettings = new MongoClientSettings
            {
                AutoEncryptionOptions = autoEncryptionSettings
            };
            var client   = new MongoClient(clientSettings);
            var database = client.GetDatabase("test");

            database.DropCollection("coll");
            var collection = database.GetCollection <BsonDocument>("coll");

            collection.InsertOne(new BsonDocument("encryptedField", "123456789"));

            var result = collection.Find(FilterDefinition <BsonDocument> .Empty).First();

            _output.WriteLine(result.ToJson());
        }