Данните често изискват висок клас сигурност на почти всяко ниво на транзакцията с данни, за да отговарят на политиките за сигурност, съответствието и правителствените разпоредби. Репутацията на организацията може да бъде разрушена, ако има неоторизиран достъп до чувствителни данни, следователно неспазване на очертания мандат.
В този блог ще обсъдим някои от мерките за сигурност, които можете да приложите по отношение на MongoDB, особено като се фокусираме върху клиентската страна на нещата.
Сценарии, при които може да се осъществява достъп до данни
Има няколко начина, по които някой може да получи достъп до вашите MongoDB данни, ето някои от тях...
- Улавяне на данни през несигурна мрежа. Някой може да получи достъп до вашите данни чрез API с VPN мрежа и ще бъде трудно да ги проследите. Данните в покой често са виновникът в този случай.
- Супер потребител като администратор с директен достъп. Това се случва, когато не успеете да дефинирате потребителски роли и ограничения.
- Имане на достъп до данни на диска, докато четете бази данни с архивни файлове.
- Четене на паметта на сървъра и регистрираните данни.
- Случайно разкриване на данни от член на персонала.
Категориите данни на MongoDB и как са защитени
По принцип всяка система от база данни включва два типа данни:
- Data-at-rest :Този, който се съхранява във файловете на базата данни
- Пренос на данни:Този, който се извършва между клиент, сървър и база данни.
MongoDB има функция за криптиране в покой, която криптира файловете на базата данни на диска, като по този начин предотвратява достъп до файлове на базата данни на диска.
Транзитните данни през мрежа могат да бъдат защитени в MongoDB чрез шифроване на транспорт, използвайки TLS/SSL чрез криптиране на данните.
В случай на случайно разкриване на данни от член на персонала, например рецепционист на екрана на работния плот, MongoDB интегрира контрола на достъп, базиран на роли, който позволява на администраторите да предоставят и ограничават разрешение на ниво колекция за потребителите.
Данните, предавани през сървъра, могат да останат в паметта и тези подходи в нито един момент не адресират опасенията за сигурността срещу достъпа до данни в паметта на сървъра. Поради това MongoDB въведе криптиране на ниво поле от страна на клиента за криптиране на специфични полета на документ, които включват поверителни данни.
Шифроване на ниво поле
MongoDB работи с документи, които имат дефинирани полета. Може да се изисква някои полета да съдържат поверителна информация, като номер на кредитна карта, номер на социално осигуряване, данни за диагноза за търпение и много други.
Шифроването на ниво поле ще ни позволи да защитим полетата и те могат да бъдат достъпни само от упълномощен персонал с ключовете за декриптиране.
Криптирането може да се извърши по два начина
- Използване на таен ключ. Използва се един ключ както за криптиране, така и за декриптиране, следователно той трябва да бъде представен при предаването на източника и местоназначението, но да се пази в тайна от всички страни.
- Използване на публичен ключ. Използва двойка ключове, като единият се използва за криптиране, а другият за декриптиране
Когато прилагате криптиране на ниво поле, помислете за използването на нова настройка на база данни, а не на съществуваща.
Шифроване на ниво поле от страна на клиента (CSFLE)
Въведено в MongoDB версия 4.2 Enterprise, за да предложи на администраторите на бази данни корекция за криптиране на полета, включващи стойности, които трябва да бъдат защитени. Това означава, че чувствителните данни се криптират или декриптират от клиента и се съобщават само към и от сървъра в криптирана форма. Освен това дори супер потребители, които нямат ключовете за криптиране, няма да имат контрол върху тези полета с криптирани данни.
Как да внедрите CSFLE
За да приложите криптирането на ниво поле от страна на клиента, ви е необходимо следното:
- MongoDB Server 4.2 Enterprise
- MongoDB Съвместим с CSFLE
- Разрешения на файловата система
- Специфични езикови драйвери. (В нашия блог ще използваме Node.js)
Процедурата по внедряване включва:
- Локална среда за разработка със софтуер за изпълнение на клиент и сървър
- Генериране и валидиране на ключовете за криптиране.
- Конфигуриране на клиента за автоматично криптиране на ниво поле
- По време на операциите по отношение на заявките на криптираните полета.
Внедряване на CSFLE
CSFLE използва стратегията за криптиране на пликове, при която ключовете за криптиране на данни се криптират с друг ключ, известен като главен ключ. Клиентското приложение създава главен ключ, който се съхранява в доставчика на локални ключове, по същество локалната файлова система. Този подход за съхранение обаче е несигурен, поради което в производството се препоръчва да конфигурирате ключа в система за управление на ключове (KMS), която съхранява и дешифрира ключовете за криптиране на данни от разстояние.
След като ключовете за криптиране на данни се генерират, те се съхраняват в колекцията на трезора в същия набор от реплики на MongoDB като криптираните данни.
Създаване на главен ключ
В node js трябва да генерираме 96-байтов локално управляван главен ключ и да го запишем във файл в директорията, от която се изпълнява основният скрипт:
$npm install fs && npm install crypto
След това в скрипта:
const crypto = require(“crypto”)
const fs = require(“fs”)
try{
fs.writeFileSync(‘masterKey.txt’, crypto.randomBytes(96))
}catch(err){
throw err;
}
Създаване на ключ за криптиране на данни
Този ключ се съхранява в колекция от хранилище с ключове, където клиентите с активиран CSFLE имат достъп до ключа за криптиране/декриптиране. За да генерирате такъв, имате нужда от следното:
- Локално управляван главен ключ
- Връзка с вашата база данни, тоест низът за връзка на MongoDB
- Пространство от имена на ключов трезор (база данни и колекция)
Стъпки за генериране на ключа за криптиране на данни
-
Прочетете генерирания локален главен ключ преди
const localMasterKey = fs.readFileSync(‘./masterKey.txt’);
-
Посочете настройките на доставчика на KMS, които ще бъдат използвани от клиента за откриване на главния ключ.
const kmsProvider = {
local: {
key: localMasterKey
}
}
-
Създаване на ключа за криптиране на данни. Трябва да създадем клиент с низа за свързване на MongoDB и конфигурацията на пространството за имена на хранилището за ключове. Да кажем, че ще имаме база данни, наречена потребители, и вътре в нея колекция keyVault. Първо трябва да инсталирате uuid-base64, като изпълните командата
$ npm install uuid-base64
След това във вашия скрипт
const base64 = require('uuid-base64');
const keyVaultNamespace = 'users.keyVaul';
const client = new MongoClient('mongodb://localhost:27017', {
useNewUrlParser: true,
useUnifiedTopology: true,
});
async function createKey() {
try {
await client.connect();
const encryption = new ClientEncryption(client, {
keyVaultNamespace,
kmsProvider,
});
const key = await encryption.createDataKey('local');
const base64DataKeyId = key.toString('base64');
const uuidDataKeyId = base64.decode(base64DataKeyId);
console.log('DataKeyId [UUID]: ', uuidDataKeyId);
console.log('DataKeyId [base64]: ', base64DataKeyId);
} finally {
await client.close();
}
}
createKey();
След това ще ви бъде представен някакъв резултат, който прилича на
DataKeyId [UUID]: ad4d735a-44789-48bc-bb93-3c81c3c90824
DataKeyId [base64]: 4K13FkSZSLy7kwABP4HQyD==
Клиентът трябва да има разрешения за четене на запис в определеното пространство от имена на ключов трезор
-
За да проверите дали ключът за криптиране на данни е създаден
const client = new MongoClient('mongodb://localhost:27017', {
useNewUrlParser: true,
useUnifiedTopology: true,
});
async function checkClient() {
try {
await client.connect();
const keyDB = client.db(users);
const keyColl = keyDB.collection(keyVault);
const query = {
_id: ‘4K13FkSZSLy7kwABP4HQyD==’,
};
const dataKey = await keyColl.findOne(query);
console.log(dataKey);
} finally {
await client.close();
}
}
checkClient();
Трябва да получите някакъв резултат от сорта
{
_id: Binary {
_bsontype: 'Binary',
sub_type: 4,
position: 2,
buffer: <Buffer 68 ca d2 10 16 5d 45 bf 9d 1d 44 d4 91 a6 92 44>
},
keyMaterial: Binary {
_bsontype: 'Binary',
sub_type: 0,
position: 20,
buffer: <Buffer f1 4a 9f bd aa ac c9 89 e9 b3 da 48 72 8e a8 62 97 2a 4a a0 d2 d4 2d a8 f0 74 9c 16 4d 2c 95 34 19 22 05 05 84 0e 41 42 12 1e e3 b5 f0 b1 c5 a8 37 b8 ... 110 more bytes>
},
creationDate: 2020-02-08T11:10:20.021Z,
updateDate: 2020-02-08T11:10:25.021Z,
status: 0,
masterKey: { provider: 'local' }
}
Върнатите данни на документа включват:идентификатор на ключа за криптиране на данни (UUID), ключ за криптиране на данни в криптирана форма, информация за доставчика на KMS за главен ключ и метаданни като ден на създаване.
Указване на полета за криптиране с помощта на JSON схема
Разширение JSON Schema се използва от драйверите на MongoDB за конфигуриране на автоматично криптиране и декриптиране от страна на клиента на посочените полета от документи в колекция. Конфигурацията на CSFLE за тази схема ще изисква:алгоритъма за криптиране, който да се използва при криптиране на всяко поле, един или всички ключове за криптиране, криптирани с главния ключ CSFLE и BSON Тип на всяко поле.
Въпреки това, тази CSFLE JSON схема не поддържа валидиране на документи, в противен случай всички екземпляри на валидиране ще накарат клиента да изведе грешка.
Клиентите, които не са конфигурирани с подходящата JSON схема от страна на клиента, могат да бъдат ограничени от записване на некриптирани данни в поле чрез използване на JSON схемата от страна на сървъра.
Има основно два алгоритма за криптиране:произволен и детерминиран.
Ще дефинираме някакъв ключ за encryptMetadata на основно ниво на JSON схемата и ще го конфигурираме с полетата, които да бъдат криптирани, като ги дефинираме в полето за свойства на схемата, така че те ще могат да наследят този ключ за криптиране .
{
"bsonType" : "object",
"encryptMetadata" : {
"keyId" : // keyId generated here
},
"properties": {
// field schemas here
}
}
Да приемем, че искате да шифровате поле за номер на банкова сметка, бихте направили нещо като:
"bankAccountNumber": {
"encrypt": {
"bsonType": "int",
"algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
}
}
Поради високата мощност и възможността за запитване на полето, ние използваме детерминистичния подход. Чувствителни полета, като например кръвна група, които имат нисък план на заявка и ниска кардиналност, могат да бъдат криптирани с помощта на произволен подход.
Полетата на масива трябва да използват произволно криптиране с CSFLE, за да подобрят автоматичното криптиране за всички елементи.
Приложение Mongocryptd
Инсталирано в MongoDB Enterprise Service 4.2 и по-нови версии, това е отделно приложение за криптиране, което автоматизира криптирането на ниво поле от страна на клиента. Всеки път, когато се създаде клиент с активиран CSFLE, тази услуга се стартира автоматично по подразбиране на:
- Проверете инструкциите за криптиране, очертани в JSON схемата, открийте кои полета трябва да бъдат криптирани в операциите за пропускателна способност.
- Предотвратете изпълнението на неподдържани операции в шифрованите полета.
За да вмъкнем данните, ще направим нормалната заявка за вмъкване и полученият документ ще има примерни данни по-долу във връзка с полето за банкова сметка.
{
…
"bankAccountNumber":"Ac+ZbPM+sk7gl7CJCcIzlRAQUJ+uo/0WhqX+KbTNdhqCszHucqXNiwqEUjkGlh7gK8pm2JhIs/P3//nkVP0dWu8pSs6TJnpfUwRjPfnI0TURzQ==",
…
}
Когато оторизиран персонал извърши заявка, водачът ще дешифрира тези данни и ще ги върне в четим формат, т.е.
{
…
"bankAccountNumber":43265436456456456756,
…
}
Забележка: Не е възможно да се правят заявки за документи в произволно криптирано поле, освен ако не използвате друго поле, за да намерите документа, който съдържа приблизителна стойност на произволно шифрованите полеви данни.
Заключение
Сигурността на данните трябва да се разглежда на всички нива по отношение на едно в състояние на покой и транзит. MongoDB Enterprise 4.2 Server предлага на разработчиците прозорец за криптиране на данни от страна на клиента, използвайки криптирането на ниво поле от страна на клиента, като по този начин осигурява защита на данните от хост доставчиците на базата данни и несигурен мрежов достъп. CSFLE използва криптиране на пликове, където главен ключ се използва за криптиране на ключове за криптиране на данни. Поради това главният ключ трябва да се съхранява в безопасност с помощта на инструменти за управление на ключове, като например Система за управление на ключове.