Skip to content

Instantly share code, notes, and snippets.

@kennwhite
Last active October 4, 2023 09:04
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kennwhite/0b3df24191eba4d04969646aca1cfeb5 to your computer and use it in GitHub Desktop.
Save kennwhite/0b3df24191eba4d04969646aca1cfeb5 to your computer and use it in GitHub Desktop.
MongoDB .NET Alpine Dockerfile CSFLE example (MSFT's Alpine SDK image and Alpine's official image)
# syntax=docker/dockerfile:1
FROM mcr.microsoft.com/dotnet/sdk:6.0-alpine3.15
# FROM alpine:3.15
#
ENV MDB_CONN_STR="mongodb+srv://user:password@clusterX.XXX.mongodb.net/test?retryWrites=true&w=majority"
#
RUN apk update
RUN apk add git make cmake g++ libbson-static musl-dev libc-dev openssl openssl-dev py3-pip icu-dev bash nano coreutils
RUN mkdir -p /code/app
WORKDIR /code/app
#
# Next commented out step is only needed if building from official Alpine image (e.g.: FROM alpine:3.15)
#
# RUN /bin/bash -c "wget https://dot.net/v1/dotnet-install.sh ;\
# chmod +x ./dotnet-install.sh ;\
# ./dotnet-install.sh --install-dir /usr/local/bin"
#
RUN /bin/bash -c "cd /code ; \
git clone --branch 1.21.1 https://github.com/mongodb/mongo-c-driver ;\
cd mongo-c-driver/ ;\
cmake -DENABLE_MONGOC=OFF . ;\
make -j8 install ;\
cd .. ;\
git clone --branch 1.3.2 https://github.com/mongodb/libmongocrypt ;\
cd libmongocrypt/ ;\
cmake . ;\
make install ;\
cd /code/app"
#
COPY app.cs /code/app/app.cs
COPY app.csproj /code/app/app.csproj
#
RUN /bin/bash -c "\
rm -rf bin obj out-standalone && \
dotnet restore && \
dotnet publish -o out-standalone -c release-standalone -r linux-musl-x64 --self-contained && \
cp /usr/local/lib/libmongocrypt.so.0.0.0 /code/app/bin/release-standalone/net6.0/linux-musl-x64/libmongocrypt.so && \
cp /usr/local/lib/libmongocrypt.so.0.0.0 /code/app/out-standalone/libmongocrypt.so && \
/code/app/bin/release-standalone/net6.0/linux-musl-x64/app &&\
/code/app/out-standalone/app && \
dotnet publish -o out -c release && \
cp /usr/local/lib/libmongocrypt.so.0.0.0 /code/app/bin/release/net6.0/runtimes/linux/native/libmongocrypt.so && \
cp /usr/local/lib/libmongocrypt.so.0.0.0 /code/app/out/runtimes/linux/native/libmongocrypt.so && \
dotnet /code/app/bin/release/net6.0/app.dll && \
dotnet /code/app/out/app.dll"
...
Step 10/10 : RUN /bin/bash -c " rm -rf bin obj out-standalone && dotnet restore && dotnet publish -o out-standalone -c release-standalone -r linux-musl-x64 --self-contained && cp /usr/local/lib/libmongocrypt.so.0.0.0 /code/app/bin/release-standalone/net6.0/linux-musl-x64/libmongocrypt.so && cp /usr/local/lib/libmongocrypt.so.0.0.0 /code/app/out-standalone/libmongocrypt.so && /code/app/bin/release-standalone/net6.0/linux-musl-x64/app && /code/app/out-standalone/app && dotnet publish -o out -c release && cp /usr/local/lib/libmongocrypt.so.0.0.0 /code/app/bin/release/net6.0/runtimes/linux/native/libmongocrypt.so && cp /usr/local/lib/libmongocrypt.so.0.0.0 /code/app/out/runtimes/linux/native/libmongocrypt.so && dotnet /code/app/bin/release/net6.0/app.dll && dotnet /code/app/out/app.dll"
---> Running in aff226097cde
Determining projects to restore...
Restored /code/app/app.csproj (in 5.17 sec).
Microsoft (R) Build Engine version 17.1.1+a02f73656 for .NET
Copyright (C) Microsoft Corporation. All rights reserved.
Determining projects to restore...
Restored /code/app/app.csproj (in 6.2 sec).
app -> /code/app/bin/release-standalone/net6.0/linux-musl-x64/app.dll
app -> /code/app/out-standalone/
Original string 123456789.
Encrypted value Encrypted:0x01ea0fcbf987f246e6b877102a51c8ed3002ae668f6318d9b11c22d16d2e5d87df843598b815f33ce7191504c431a4151a93c39e549d252d203ddeaa1a25f794408768195c3f89169b538695bf794478a5c1.
Decrypted document { "_id" : ObjectId("626210cdbb70ab135935e0fd"), "encryptedField" : "123456789" }.
Original string 123456789.
Encrypted value Encrypted:0x0115c1d973d69941b99e696be705b8590302295aac6b6afdb836385492ccbce3913e701895fb74ac02dcc3de65a671483296f3360591f182b30544af4e901e8e9122d54fa07d131b3bff323e1859bf3041c5.
Decrypted document { "_id" : ObjectId("626210cfc71c4cc2769c1db9"), "encryptedField" : "123456789" }.
Microsoft (R) Build Engine version 17.1.1+a02f73656 for .NET
Copyright (C) Microsoft Corporation. All rights reserved.
Determining projects to restore...
Restored /code/app/app.csproj (in 282 ms).
app -> /code/app/bin/release/net6.0/app.dll
app -> /code/app/out/
Original string 123456789.
Encrypted value Encrypted:0x017685ff481925456f9ffd4e37f852e68102c756a5d7f95002dc21affbe5e1594e1b804de790c99e3ae2c119720be0631a62a075f418276eff3212570084e5fb9fef630b197e707e80f77cf2c471afe87ee2.
Decrypted document { "_id" : ObjectId("626210d36f4a4b20314fa25c"), "encryptedField" : "123456789" }.
Original string 123456789.
Encrypted value Encrypted:0x01d9be2bacbff04731b16f0ce3ae6fa4f502ba950b61cb4b1a5bb27c8862e91c3fb5be46d0fb88a676779e9d252deeb9869c2fbd0b01bf0a333cb35679908e856df99ceea11b4f29e44f3b96a6dee33fc6d4.
Decrypted document { "_id" : ObjectId("626210d512050d1b2ff178a1"), "encryptedField" : "123456789" }.
Removing intermediate container aff226097cde
---> 7717aa614c68
Successfully built 7717aa614c68
Successfully tagged builder:latest
root@ubuntu:~/build#
#
// app.cs (the "x_" prefix is a workaround for gist's goofy display ordering; please save as just "app.cs")
// From: https://mongodb.github.io/mongo-csharp-driver/2.15/reference/driver/crud/client_side_encryption/#explicit-encryption-and-auto-decryption
using System;
using System.IO;
using System.Collections.Generic;
using System.Threading;
using MongoDB.Bson;
using MongoDB.Driver;
using MongoDB.Driver.Encryption;
public class ExplicitEncryptionAndAutoDecryptionExamples
{
private const string LocalMasterKey = "Mng0NCt4ZHVUYUJCa1kxNkVyNUR1QURhZ2h2UzR2d2RrZzh0cFBwM3R6NmdWMDFBMUN3YkQ5aXRRMkhGRGdQV09wOGVNYUMxT2k3NjZKelhaQmRCZGJkTXVyZG9uSjFk";
// private const string ConnectionString = "mongodb+srv://user:password@cluster0.xxx.mongodb.net/test?retryWrites=true&w=majority";
public static string? ConnectionString = Environment.GetEnvironmentVariable("MDB_CONN_STR");
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 keyVaultNamespace = CollectionNamespace.FromFullName("keyvault.datakeys");
var collectionNamespace = CollectionNamespace.FromFullName("test.coll");
var autoEncryptionOptions = new AutoEncryptionOptions(
keyVaultNamespace,
kmsProviders,
bypassAutoEncryption: true);
var clientSettings = MongoClientSettings.FromConnectionString( ConnectionString );
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( ConnectionString );
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";
Console.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);
Console.WriteLine($"Encrypted value {encryptedFieldValue}.");
collection.InsertOne(new BsonDocument("encryptedField", encryptedFieldValue));
// Automatically decrypts the encrypted field.
var decryptedValue = collection.Find(FilterDefinition<BsonDocument>.Empty).First();
Console.WriteLine($"Decrypted document {decryptedValue.ToJson()}.");
}
}
}
<!-- (the "x_" prefix is a workaround for gist's goofy display ordering; please save as just "app.csproj") -->
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="MongoDB.Bson" Version="2.15.0" />
<PackageReference Include="MongoDB.Driver" Version="2.15.0" />
<PackageReference Include="MongoDB.Driver.Core" Version="2.15.0" />
</ItemGroup>
</Project>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment