-
Type: Bug
-
Resolution: Done
-
Priority: Major - P3
-
None
-
Affects Version/s: 2.10.4
-
Component/s: Field Level Encryption
-
None
-
(copied to CRM)
Steps to reproduce (using Visual Studio 2019 and a local MongoDB 4.2-ent cluster)
1 - Create an ASP.NET Web Application / Web API project
2 - Enable Tools > Options > Project and Solutions > Web Projects and check the option > "Use the 64 bit version of IIS Express for web sites and projects"
3 - Set the project's Platform Target to x64
3 - Using the NuGet Package Manager, install MongoDB.Driver (2.10.4) and MongoDB.Libmongocrypt (1.0.0)
4 - Copy the following code to Controllers\ValuesController.cs:
Unable to find source-code formatter for language: csharp. Available languages are: actionscript, ada, applescript, bash, c, c#, c++, cpp, css, erlang, go, groovy, haskell, html, java, javascript, js, json, lua, none, nyan, objc, perl, php, python, r, rainbow, ruby, scala, sh, sql, swift, visualbasic, xml, yaml
using MongoDB.Bson; using MongoDB.Driver; using MongoDB.Driver.Encryption; using System; using System.Collections.Generic; using System.Linq; using System.Threading; using System.Web.Http; namespace WebApplication1.Controllers { public class ValuesController : ApiController { private MongoClient GetCSFLEClient() { var localMasterKey = Convert.FromBase64String("Mng0NCt4ZHVUYUJCa1kxNkVyNUR1QURhZ2h2UzR2d2RrZzh0cFBwM3R6NmdWMDFBMUN3YkQ5aXRRMkhGRGdQV09wOGVNYUMxT2k3NjZKelhaQmRCZGJkTXVyZG9uSjFk"); 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 schemaMap = $@"{{ properties: {{ encryptedField: {{ encrypt: {{ keyId: [{{ '$binary' : {{ 'base64' : '{base64DataKeyId}', 'subType' : '04' }} }}], bsonType: 'string', algorithm: 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic' }} }} }}, 'bsonType': 'object' }}"; var collectionNamespace = CollectionNamespace.FromFullName("test.coll"); var autoEncryptionSettings = new AutoEncryptionOptions( keyVaultNamespace, kmsProviders, schemaMap: new Dictionary<string, BsonDocument>() { { collectionNamespace.ToString(), BsonDocument.Parse(schemaMap) } }); var clientSettings = new MongoClientSettings { AutoEncryptionOptions = autoEncryptionSettings }; return new MongoClient(clientSettings); } // GET api/values public IEnumerable<string> Get(bool csfle) { var client = (csfle) ? GetCSFLEClient() : new MongoClient(); 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(); return new string[] { result.ToJson() }; } } }
5 - Build / Run
Using the following should succeed:
https://localhost:44373/api/Values?csfle=false
<ArrayOfstring xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/2003/10/Serialization/Arrays"> <string>{ "_id" : ObjectId("5ed63b324eecb9086ccccaf2"), "encryptedField" : "123456789" }</string> </ArrayOfstring>
Using the following should fail:
https://localhost:44373/api/Values?csfle=true
<Error> <Message>An error has occurred.</Message> <ExceptionMessage> Could not find: mongocrypt.dll -- Tried: C:\Users\Administrator\AppData\Local\Temp\Temporary ASP.NET Files\vs\85bbc5a0\ab21fb48\assembly\dl3\cd3d81d3\009d89cc_8b9ad501\..\..\x64\native\windows\mongocrypt.dll,C:\Users\Administrator\AppData\Local\Temp\Temporary ASP.NET Files\vs\85bbc5a0\ab21fb48\assembly\dl3\cd3d81d3\009d89cc_8b9ad501\mongocrypt.dll </ExceptionMessage> <ExceptionType>System.IO.FileNotFoundException</ExceptionType> <StackTrace> at MongoDB.Libmongocrypt.LibraryLoader.FindLibrary(IList`1 basePaths, String[] suffixPaths, String library) at MongoDB.Libmongocrypt.LibraryLoader..ctor() at MongoDB.Libmongocrypt.Library.<>c.<.cctor>b__0_46() at System.Lazy`1.CreateValue() at System.Lazy`1.LazyInitValue() at MongoDB.Libmongocrypt.Library.<>c.<.cctor>b__0_1() at System.Lazy`1.CreateValue() at System.Lazy`1.LazyInitValue() at MongoDB.Libmongocrypt.CryptClientFactory.Create(CryptOptions options) at MongoDB.Driver.Core.Clusters.CryptClientCreator.CreateCryptClient(IReadOnlyDictionary`2 kmsProviders, IReadOnlyDictionary`2 schemaMap) at MongoDB.Driver.Encryption.ClientEncryption..ctor(ClientEncryptionOptions clientEncryptionOptions) at WebApplication1.Controllers.ValuesController.GetCSFLEClient() in C:\Users\Administrator\source\repos\WebApplication1\WebApplication1\Controllers\ValuesController.cs:line 32 at WebApplication1.Controllers.ValuesController.Get(Boolean csfle) in C:\Users\Administrator\source\repos\WebApplication1\WebApplication1\Controllers\ValuesController.cs:line 75 at lambda_method(Closure , Object , Object[] ) at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.<>c__DisplayClass6_2.<GetExecutor>b__2(Object instance, Object[] methodParameters) at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ExecuteAsync(HttpControllerContext controllerContext, IDictionary`2 arguments, CancellationToken cancellationToken) --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Web.Http.Controllers.ApiControllerActionInvoker.<InvokeActionAsyncCore>d__1.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Web.Http.Controllers.ActionFilterResult.<ExecuteAsync>d__5.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__15.MoveNext() </StackTrace> </Error>