MongoDB 6 şu yeteneği tanıttı: şifrelenmiş verileri sorgula veritabanında. Veriler, tüm gidiş dönüş için şifrelenir: ekleme, depolama ve sorgulama sırasında. Bu, veri tabanında kullanıldığında bile güvenli kalan veriler için yeni bir güvenlik düzeyi anlamına gelir. Yalnızca istemci uygulaması verilerin şifresini çözebilir. Veritabanı, şifrelenmiş verilerin anahtarlarını hiç tutmaz, ancak yine de bu verilerin sorgulanmasını destekler.
Böylece MongoDB sorgulanabilir şifreleme, veri deposunu ve altyapısını saldırı hedefi olarak kaldırır. Bu yarı sihirli yetenek, uygulamalar için bazı ekstra yapılandırmalar gerektirir. Bu makale, bir Node.js uygulamasında MongoDB sorgulanabilir şifreleme ile çalışmak için bir geliştirme ortamının nasıl kurulacağını gösterecektir.
Ana ve veri şifreleme anahtarları
MongoDB’nin sorgulanabilir şifrelemesinde kullanılan iki tür anahtar vardır: müşteri ana anahtarı (CMK) ve veri şifreleme anahtarları (DEK’ler). Bunlar, verilerinizin güvenliğini sağlamak için birlikte çalışır. DEK, veritabanındaki verileri şifrelemek için kullanılırken, CMK, bir koruma katmanı ekleyerek DEK’i şifrelemek ve şifresini çözmek için kullanılır. CMK daha hassas anahtardır. CMK’nın güvenliği ihlal edilirse, verileriniz tehlikeye açık hale gelir. CMK veya DEK kaybolur veya erişilemezse, istemci uygulaması verilerin şifresini çözemez.
Sorgulanabilir şifreleme kullanacak bir uygulama geliştirirken, uzak anahtar deposu yerine CMK’nizi uygulama ile aynı sunucuda tutan yerel bir dosya kullanabilirsiniz. Üretimde, uzak bir anahtar deposu kullanmanız gerektiğini, aksi takdirde sistemin güvenliğini baltalayacağınızı önceden not etmek önemlidir.
CMK oluştur
İlk adım, CMK’nizi oluşturmaktır. Bunu, Liste 1’de gösterildiği gibi openssl komut satırı aracıyla yapabilirsiniz.
Liste 1. Yerel bir anahtar oluşturun
openssl rand 96 > cmk.txt
DEK oluştur
CMK’mızı işlemek için basit bir Node.js programı oluşturacağız, bir DEK oluşturacağız ve DEK’i MongoDB’de adı verilen özel bir şifreli koleksiyona ekleyeceğiz. anahtar kasası. Sorgulanabilir şifreleme, bu koleksiyonda CMK ile şifrelenmiş DEK’i tutar. Şifrelenmiş uygulama verilerine karşı çağrı yaparken, istemci uygulamanız anahtar kasasından DEK’i alır, CMK ile DEK’in şifresini çözer ve ardından veritabanı örneğiyle etkileşim kurmak için şifresi çözülen DEK’i kullanır.
Bu çok fazla şifreleme oluyor, ancak yine fikir, CMK sayesinde DEK’i güvende tutmaktır.
MongoDB belgeleri, DEK anahtar kasası tablosunu oluşturmak için kullanılan uygulamanın daha tam olarak gerçekleştirilmiş bir sürümünü sağlar. burada. Ağaçların arasından ormanı görebilmek için en azını yapacağız.
npm init yazarak yeni bir NPM uygulaması oluşturun. Tüm varsayılanları kabul edebilirsiniz. Şimdi make-dek.js ve insert.js adında iki yeni js dosyası oluşturun ve Listing 2 gibi package.json dosyasındaki satırları ekleyin.
Liste 2. makeDEK betiği
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"makeDEK": "node ./make-dek.js",
"insert": "node ./insert.js"
}
Artık makeDEK.js’yi girerek çalıştırabilirsiniz. npm run makeDEK
ve npm run insert
komut satırında. (Ama bu komutlar henüz bir şey yapmayacak.)
Bağımlılık ekle
Sonraki adımlar için kurulu iki pakete ihtiyacımız olacak. Yüklemek için Liste 3’teki komutları girin.
Liste 3. MondoDB bağımlılıkları ekleyin
npm install mongodb
npm install mongodb-client-encryption
MongoDB Atlas’ı kurun
Bu eğitim için MongoDB’nin yönetilen hizmeti Atlas’ı kullanacağız. Bu yazı itibariyle, Atlas’ta bir MongoDB 6 kümesi oluşturmak için ücretli katmanlı bir özel kümeye ihtiyacınız olacak. (MongoDB Community Server ile manuel modda sorgulanabilir şifreleme kullanmanın mümkün olduğunu unutmayın.)
Ücretsiz bir Atlas hesabı oluşturabilirsiniz burada. Buradan, kümeyi kurmak (adı Cluster0 olarak bırakarak) ve parola doğrulaması olan bir kullanıcı oluşturmak kolaydır. Bu seçeneği aldığınızda “Adanmış Küme”yi seçtiğinizden emin olun.
Bu adımları gerçekleştirmek için kullanıcının AtlasAdmin rolüne sahip olması gerektiğini unutmayın. MongoDB konsolunda “Veritabanı Erişimi”ne gidip kullanıcınızın yanındaki “Düzenle”ye tıklayarak kullanıcı üzerindeki rolü belirleyebilirsiniz. Ardından “Yerleşik Rol” açılır menüsünde AtlasAdmin’i seçin.
Atlas kümesine erişmek için sonraki adımlarda kullanıcı adını ve parolayı kullanacağız.
Lütfen dikkat (güvenlik uyarısı):
- Gerçek dünya kullanımında, şema ve dizinler oluşturulduktan sonra koleksiyonlara erişmek için AtlasAdmin gibi global izinli bir kullanıcı kullanmayın. İşlerini yapmak için yeterli izne sahip kullanıcılar oluşturun. Şemayı ve dizinleri oluşturduktan sonra, koleksiyonlara (şifreli olanlar dahil) erişmek için normal bir rol kullanabilirsiniz.
- Gerçek bir uygulamada, aşağıda yapacağımız gibi, veritabanı kimlik bilgilerinizi koda eklemezsiniz. Gerçek bir uygulamada, bir ortam değişkeni veya yapılandırma dosyası kullanın.
Paylaşılan crypt kitaplığı ekle
MongoDB, iki sorgulanabilir şifreleme stilini destekler: otomatik ve manuel. Auto daha basittir ve MongoDB istemcisinin sizin için şifreleme konusunda anlaşmaya varmasına izin verir. Auto’yu kullanmak için, MongoDB’den sağlanan paylaşılan şifreleme kitaplığına ihtiyacınız var. burada. Sağdaki açılır menüden crypt_shared’i seçin, işletim sisteminizi belirtin ve Ekran Görüntüsü 1’deki gibi en son sürümü kullanın (lisansı kabul etmek için bir e-posta adresi de gireceksiniz.)
Ekran Görüntüsü 1. crypt_shared paketini indirin
Şimdi bu dosyayı uygun bir yere koyun ve sıkıştırmasını açın/açın. Çıkarma ile oluşturulan dizinde bir /lib/mongo_crypt_v1.so dosyası bulacaksınız. İhtiyacımız olan bu. Yolu not edin çünkü daha sonra Liste 4 ve Liste 5’te
make-dek.js kodu
Artık make-dek.js dosyasının kodunu yazmaya hazırız. Bu, anahtar kasası koleksiyonunu ve şifreli koleksiyonun kendisini ayarlayan küçük bir uygulama olacaktır. Bu iki koleksiyon, şifrelenmiş koleksiyondan kalıcı, sorgulama ve veri alma işlemlerini işlemek için birlikte çalışır. (Bu, MongoDB belgelerinde daha ayrıntılı olarak ele alınmaktadır.) make-dek.js’nin içeriği Liste 4’te gösterilmektedir.
Liste 4. make-dek.js
const { MongoClient, Binary } = require("mongodb");
const { ClientEncryption } = require("mongodb-client-encryption");const keyVaultNamespace = "encryption.__keyvault";
const secretDB = "secretDB";
const secretCollection = "secretCollection";
const uri = "mongodb+srv://<ATLAS_USERNAME>:<ATLAS_PASSWORD>@cluster0.444xyz.mongodb.net/?retryWrites=true&w=majority";async function run() {
const keyVaultClient = new MongoClient(uri);
await keyVaultClient.connect();
const keyVaultDB = keyVaultClient.db("encryption");
await keyVaultDB.dropDatabase();
const keyVaultColl = keyVaultDB.collection("__keyvault");
await keyVaultColl.createIndex(
{ keyAltNames: 1 },
{ unique: true, partialFilterExpression: { keyAltNames: { $exists: true } } }
);
const localMasterKey = require("fs").readFileSync("./cmk.txt");
const kmsProviders = { local: { key: localMasterKey } };
const clientEnc = new ClientEncryption(keyVaultClient, {
keyVaultNamespace: keyVaultNamespace,
kmsProviders: kmsProviders
});
const dek = await clientEnc.createDataKey("local", { keyAltNames: ["dek"] });
const encryptedFieldsMap = {
["secretDB.secretCollection"]: {
fields: [
{
keyId: dek,
path: "secretField",
bsonType: "int",
queries: { queryType: "equality" },
}
]
}
};
const extraOptions = { cryptSharedLibPath: "<MONGO_CRYPT_LIB_PATH>" };
const encClient = new MongoClient(uri, {
autoEncryption: {
keyVaultNamespace,
kmsProviders,
extraOptions,
encryptedFieldsMap
}
});await encClient.connect();
const newEncDB = encClient.db(secretDB);
await newEncDB.dropDatabase();
await newEncDB.createCollection(secretCollection);
await keyVaultClient.close();
await encClient.close();
console.log("Successfully created DEK and encrypted collection.");
}run().catch(console.dir);
Liste 4, iki koleksiyonun hikayesini anlatıyor: encryption.__keyvault
ve secretDB.secretCollection
. Bu iki koleksiyon, sorgulanabilir şifrelemeyi desteklemek için birlikte kullanılır.
secretDB.secretCollection
gerçek iş verilerini oteller. bu encryption.__keyvault
koleksiyon, üzerinde kullanılan şifrelenmiş veri şifreleme anahtarlarını tutar. secretDB.secretCollection
. Kullanımda iki MongoClient var. Şifrelenmiş istemci (encClient
) şifrelenmemiş tarafından oluşturulan DEK ile yapılandırılır. keyVaultClient
. DEK, encryptedFieldsMap.keyId
yapılandırmak için kullanılan alan encClient
.
bu encryptedFieldsMap
şifrelenmiş istemci için daha fazla bilgi tutar encClient
bir standart olan MongoClient
ile ayarla autoEncrypted
alan doldurulur. bu encryptedFieldsMap
istemciye hangi alanların şifrelendiğini söyler (path özelliği ile), bu durumda secretField
. Eğer queries
özellik ayarlanmazsa, alan şifrelenir ancak sorgulanamaz. Bu yazı itibariyle sadece equality
olarak desteklenir queryType
.
Dikkat edin ki bir ClientEncryption
nesne (clientEnc
) DEK’i oluşturmak için kullanılır. bu clientEnc
nesne kullanır keyVaultClient
ile birlikte keyVaultNameSpace
(encryption.__keyvault
) ve kmsProvider
.
bu kmsProvider
komut satırında oluşturduğumuz rastgele sayıya işaret eden yerel bir anahtar sağlayıcıdır. tarafından da kullanılmaktadır. autoEncryption
üzerine koyduk encClient
müşteri. (Hatırlatma: Yerel kmsProvider
üretimde.)
Veri ekleme ve sorgulama
Artık verileri eklemek ve sorgulamak için altyapıya sahibiz. secretDB.secretCollection.secretField
. Bu, içindeki anahtarlar kullanılarak yapılır. encryption.__keyvault
. Liste 5, şifrelenmemiş iki alanla bunu yapmanın soyulmuş bir örneğini sunar. string
üzerinde nonsecretField
ve şifreli int
üzerinde secretField
.
Listeleme 5. Şifreli ve şifresiz alanlara ekleme ve sorgulama
const { MongoClient, Binary } = require("mongodb");const localMasterKey = require("fs").readFileSync("./cmk.txt");
const kmsProviders = { local: { key: localMasterKey } };
const uri = "mongodb+srv://<ATLAS_USERNAME>:
<ATLAS_PASSWORD>@cluster0.444xyz.mongodb.net/?retryWrites=true&w=majority"async function run() {
const unencryptedClient = new MongoClient(uri);
await unencryptedClient.connect();
const keyVaultClient = unencryptedClient.db("encryption").collection("__keyvault");
const dek = await keyVaultClient.findOne({ "keyAltNames": "dek" });const encryptedFieldsMap = {
["secretDB.secretCollection"]: {
fields: [
{
keyId: dek._id,
path: "secretField",
bsonType: "int",
queries: { queryType: "equality" }
}
]
}
};
const extraOptions = { cryptSharedLibPath: "<MONGO_CRYPT_LIB_PATH>" };
const encryptedClient = new MongoClient(uri, {
autoEncryption: {
keyVaultNamespace: "encryption.__keyvault",
kmsProviders: kmsProviders,
extraOptions: extraOptions,
encryptedFieldsMap: encryptedFieldsMap
}
});
await encryptedClient.connect();
try {
const unencryptedColl = unencryptedClient.db("secretDB").collection("secretCollection");
const encryptedColl = encryptedClient.db("secretDB").collection("secretCollection");
await encryptedColl.insertOne({
secretField: 42,
nonsecretField: "What is the secret to life, the universe and everything?"
});
console.log(await unencryptedColl.findOne({ nonsecretField: /universe/ }));
console.log(await encryptedColl.findOne({ "secretField":42 })
);
} finally {
await unencryptedClient.close();
await encryptedClient.close();
}
}run().catch(console.dir);
Liste 5’te iki MongoDB istemcisi, şifrelenmemiş bir istemci ve şifreli bir istemci oluşturuyoruz. İle birlikte unencryptedClient
anahtar kasasına erişiyoruz encryption.__keyvault
Liste 4’te make-dek.js ile oluşturduğumuz ve orada depoladığımız DEK’i alıyoruz. Daha sonra DEK’i inşa etmek için kullanırız. encryptedFieldsMap
Gizli alan için yol, tür ve sorgu ayarlarını da tutan .
Ardından, keyvault ad alanını (encryption.__keyvault
), kmsProvider
(yine cmk.txt’deki yerel dosyadır), extraOptions
MongoDB’den indirdiğimiz paylaşılan crypt kitaplığına işaret ederek ve encryptedFieldsMap
.
Sonra kullanırız encryptedClient
içine sokmak secretDB.secretCollection
ile toplama, secretField
ve nonsecretField
ayarlamak int
ve bir string
sırasıyla.
Son olarak verileri sorguluyoruz. İlk önce şifrelenmemiş istemciyi kullanıyoruz – bu sefer secretDB.secretCollection
– kullanarak sorgulamak için nonsecretField
ve sonucu yazdırın. Sonuç gösterecektir ki, secretField
şifreli metindir, nonsecretField
düz metindir. Buradaki nokta, şifrelenmemiş istemcinin normal alanları her zamanki gibi sorgulayabilmesi ve kullanabilmesidir.
Şifrelenmiş istemci daha sonra aşağıdakilere karşı sorgulama yapmak için kullanılır. secretField
ve bu sonuç çıktı olduğunda, dahil tüm alanlar secretField
görülebilir. Bu gösteriyor ki encryptedClient
tüm alanlara tam erişime sahiptir.
Dikkat secretDB.secretCollection
ayrıca meta verileri bir __safeContent__
alan. Bunu veya anahtar kasası koleksiyonunu değiştirmediğinizden emin olun, aksi takdirde işler beklendiği gibi çalışmayabilir.
Sorgulayabileceğiniz şifreleme
MongoDB sorgulanabilir şifreleme, şifrelenmemiş verilerden ve hatta normal şifreli verilerden daha fazla geliştirme çabası gerektirir, ancak aynı zamanda başka yollarla elde edilemeyen bir yeteneği de sağlar: anahtarlarından ayrı olarak şifrelenmiş verileri sorgulama. Bu, hassas veriler için yüksek düzeyde güvenlik sağlar. Hem maksimum veri güvenliği hem de sorgulanabilirlik gerektiren işletmeler için MongoDB’nin sorgulanabilir şifrelemesi olmazsa olmaz bir özellik olabilir.
Telif Hakkı © 2022 IDG Communications, Inc.
Kaynak : https://www.infoworld.com/article/3675390/hands-on-with-mongodb-queryable-encryption-and-node-js.html#tk.rss_all