Watch keynotes and sessions from MongoDB.live, our virtual developer conference.

Testing Client Side encryption locally, returning null value

I’ve been following the encryption guide here for generating data encryption keys for the client side encryption process https://docs.mongodb.com/drivers/use-cases/client-side-field-level-encryption-guide

I’m trying to test client side encryption locally to a database that I upgraded from community edition to enterprise but I always get null when I try to do the verification step in Section B Step 4. Does a brand new encryption database have to be created for this to work? I was hoping just to add __keyvault to the existing db i have locally

Just for some more specifics I have the following code to generate the data encryption key

const fs = require('fs-extra')
const { MongoClient } = require('mongodb');
const { ClientEncryption } = require('mongodb-client-encryption')


const path = './master-key.txt';
const localMasterKey = fs.readFileSync(path);

const kmsProviders = {
    local: {
        key: localMasterKey,
    },
};

const base64 = require('uuid-base64');

const username = process.env.PAPER_DB_USER
const pass = process.env.PAPER_DB_PASS

const connectionString = `mongodb://${username}:${pass}@localhost:27017`;
const keyVaultNamespace = 'db.__keyVault';
const client = new MongoClient(connectionString, {
  useNewUrlParser: true,
  useUnifiedTopology: true,
});

async function main() {
  try {
    await client.connect();
    console.log("hello  clientEncryption")
    const encryption = new ClientEncryption(client, {
      keyVaultNamespace,
      kmsProviders,
    });
    console.log("done")
    const key = await encryption.createDataKey('local');
    console.log("key made")
    const base64DataKeyId = key.toString('base64');
    console.log("base64 key made")
    const uuidDataKeyId = base64.decode(base64DataKeyId);
    console.log('DataKeyId [UUID]: ', uuidDataKeyId);
    console.log('DataKeyId [base64]: ', base64DataKeyId);
  } finally {
    await client.close();
  }
}
main();

Output: image

Then I use the following code to verify:

 const { MongoClient } = require('mongodb');

const username = process.env.PAPER_DB_USER
const pass = process.env.PAPER_DB_PASS

const connectionString = `mongodb://${username}:${pass}@localhost:27017`;
const keyVaultDb = 'db';
const keyVaultCollection = '__keyVault';
const base64KeyId = '6exu+2ObR8yYaQo/RJe5Gw=='; // use the base64 data key id returned by gen_data_encrypt_key.js in the prior step

const client = new MongoClient(connectionString, {
  useNewUrlParser: true,
  useUnifiedTopology: true,
});

const base64 = require('uuid-base64');

async function main() {
  try {
    await client.connect();
    const keyDB = client.db(keyVaultDb);
    const keyColl = keyDB.collection(keyVaultCollection);

    console.log("base64KeyId", base64KeyId)
    const uuidDataKeyId = base64.decode(base64KeyId);
    console.log("uuidDataKeyId ", uuidDataKeyId)
    const query = {
      _id: base64KeyId,
    };
    const dataKey = await keyColl.findOne(query);
    console.log(dataKey);
  } finally {
    await client.close();
  }
}
main();

Output: image

And this is what it looks like on the __keyvault connection in the database

Lastly this is the version of mongoDB that I am currently using
image

For now I can’t figure out how to make it show with just querying base 64 string, I ended up using another package uuid-mongodb https://www.npmjs.com/package/uuid-mongodb to decode it, then put it back into its proper uuid and then the query would work. Not ideal but it functions

...
const UUID = require('uuid-mongodb');
const uuidDataKeyId = UUID.from(base64.decode(base64KeyId));
console.log("uuidDataKeyId ", uuidDataKeyId)
console.log("typeof uuidDataKeyId", typeof uuidDataKeyId)
const query = {
  _id: uuidDataKeyId,
};
const dataKey = await keyColl.findOne(query);
console.log(dataKey);

After I finally dont get a null result
image