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