Docs 菜单
Docs 主页
/ / /
Scala
/

客户端加密

在此页面上

  • 安装
  • libmongocrypt
  • mongocryptd 配置
  • 示例
  • 自动加密和解密
  • 指定数据加密密钥和加密字段
  • 显式加密和解密
  • 显式加密和自动解密

从 v 4.2开始, MongoDB 支持客户端加密。 除了提供其他 MongoDB 加密功能外,客户端加密还允许管理员和开发人员加密特定数据字段。

通过字段级加密,开发者可以在客户端加密字段,无需任何服务器端配置或指令。 客户端字段级加密支持的工作负载中,应用程序必须保证包括服务器管理员在内的未经授权方无法读取加密数据。

注意

本指南使用 Observable隐式,如快速入门入门知识中所述。

在项目中开始使用字段级加密的推荐方法是使用依赖项管理系统。 除驱动程序外,字段级加密还需要其他软件包。

注意

有关如何安装 Scala 驱动程序的说明,请参阅安装指南。

有一个单独的 JAR 文件,其中包含libmongocrypt绑定。

如果您使用的是 Maven 要管理您的软件包,请将以下条目添加到您的pom.xml 依赖项列表中:

<dependencies>
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongodb-crypt</artifactId>
<version>1.2.1</version>
</dependency>
</dependencies>

如果您使用 Gradle 要管理您的包,请将以下条目添加到您的依赖项列表中:

dependencies {
implementation 'org.mongodb:mongodb-crypt:1.2.1'
}

libmongocrypt绑定要求mongocryptd守护进程/进程正在运行。 可以通过在extraOptions设置中设置mongocryptdURI ,在AutoEncryptionSettings类中配置特定的守护进程/进程 URI。

以下示例是一个示例应用,它假设已在MongoDB中创建密钥和模式。 该示例使用本地密钥,但您也可以使用Amazon Web Services / Azure / GCP KMS 。 encryptedField字段中的数据在插入时自动加密,在客户端端使用查找时自动解密。

代码示例来自 ClientSideEncryptionSimpleTour.scala 驾驶员源代码Github 存储库中的文件。

import java.security.SecureRandom
import org.mongodb.scala.{AutoEncryptionSettings, Document, MongoClient, MongoClientSettings}
import tour.Helpers._
import scala.collection.JavaConverters._
object ClientSideEncryptionSimpleTour {
def main(args: Array[String]): Unit = {
val localMasterKey = new Array[Byte](96)
new SecureRandom().nextBytes(localMasterKey)
val kmsProviders = Map("local" -> Map[String, AnyRef]("key" -> localMasterKey).asJava).asJava
val keyVaultNamespace = "admin.datakeys"
val autoEncryptionSettings = AutoEncryptionSettings.builder()
.keyVaultNamespace(keyVaultNamespace).kmsProviders(kmsProviders).build()
val clientSettings = MongoClientSettings.builder()
.autoEncryptionSettings(autoEncryptionSettings).build()
val mongoClient = MongoClient(clientSettings)
val collection = mongoClient.getDatabase("test").getCollection("coll")
collection.drop().headResult()
collection.insertOne(Document("encryptedField" -> "123456789")).headResult()
collection.find().first().printHeadResult()
// release resources
mongoClient.close()
}
}

注意

自动加密是企业独有的功能。

以下示例展示了如何配置AutoEncryptionSettings实例以创建新密钥并设立JSON schema映射。

代码示例来自 ClientSideEncryptionAutoEncryptionSettingsTour.scala 驾驶员源代码Github 存储库中的文件。

import java.security.SecureRandom
import java.util.Base64
import scala.collection.JavaConverters._
import org.mongodb.scala._
import org.mongodb.scala.bson.BsonDocument
import org.mongodb.scala.model.vault.DataKeyOptions
import org.mongodb.scala.vault.ClientEncryptions
import tour.Helpers._
...
val keyVaultNamespace = "admin.datakeys"
val clientEncryptionSettings = ClientEncryptionSettings.builder()
.keyVaultMongoClientSettings(
MongoClientSettings.builder().applyConnectionString(ConnectionString("mongodb://localhost")).build())
.keyVaultNamespace(keyVaultNamespace).kmsProviders(kmsProviders).build()
val clientEncryption = ClientEncryptions.create(clientEncryptionSettings)
val dataKey = clientEncryption.createDataKey("local", DataKeyOptions()).headResult()
val base64DataKeyId = Base64.getEncoder.encodeToString(dataKey.getData)
val dbName = "test"
val collName = "coll"
val autoEncryptionSettings = AutoEncryptionSettings.builder()
.keyVaultNamespace(keyVaultNamespace)
.kmsProviders(kmsProviders)
.schemaMap(Map(s"$dbName.$collName" -> BsonDocument(
s"""{
properties: {
encryptedField: {
encrypt: {
keyId: [{
"$$binary": {
"base64": "$base64DataKeyId",
"subType": "04"
}
}],
bsonType: "string",
algorithm: "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
}
}
},
bsonType: "object"
}""")).asJava)
.build()

显式加密和解密是MongoDB Community的一项功能,不使用 mongocryptd 进程。 显式加密由ClientEncryption类提供。

代码示例来自 ClientSideEncryptionExplicitEncryptionAndDecryptionTour.scala 驾驶员源代码Github 存储库中的文件。

// This would have to be the same master key as was used to create the encryption key
val localMasterKey = new Array[Byte](96)
new SecureRandom().nextBytes(localMasterKey)
val kmsProviders = Map("local" -> Map[String, AnyRef]("key" -> localMasterKey).asJava).asJava
val keyVaultNamespace = new MongoNamespace("encryption.testKeyVault")
val clientSettings = MongoClientSettings.builder().build()
val mongoClient = MongoClient(clientSettings)
// Set up the key vault for this example
val keyVaultCollection = mongoClient.getDatabase(keyVaultNamespace.getDatabaseName)
.getCollection(keyVaultNamespace.getCollectionName)
keyVaultCollection.drop().headResult()
// Ensure that two data keys cannot share the same keyAltName.
keyVaultCollection.createIndex(Indexes.ascending("keyAltNames"), new IndexOptions().unique(true)
.partialFilterExpression(Filters.exists("keyAltNames")))
val collection = mongoClient.getDatabase("test").getCollection("coll")
collection.drop().headResult()
// Create the ClientEncryption instance
val clientEncryptionSettings = ClientEncryptionSettings
.builder()
.keyVaultMongoClientSettings(
MongoClientSettings.builder()
.applyConnectionString(ConnectionString("mongodb://localhost")).build()
)
.keyVaultNamespace(keyVaultNamespace.getFullName)
.kmsProviders(kmsProviders)
.build()
val clientEncryption = ClientEncryptions.create(clientEncryptionSettings)
val dataKeyId = clientEncryption.createDataKey("local", DataKeyOptions()).headResult()
// Explicitly encrypt a field
val encryptedFieldValue = clientEncryption.encrypt(BsonString("123456789"),
EncryptOptions("AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic").keyId(dataKeyId))
.headResult()
collection.insertOne(Document("encryptedField" -> encryptedFieldValue)).headResult()
val doc = collection.find.first().headResult()
println(doc.toJson())
// Explicitly decrypt the field
println(
clientEncryption.decrypt(doc.get[BsonBinary]("encryptedField").get).headResult()
)

虽然自动加密需要MongoDB 4.2企业版或MongoDB 4.2 Atlas 集群,支持所有用户自动解密。 要配置自动解密而不自动加密,设立bypassAutoEncryption(true)

代码示例来自 ClientSideEncryptionExplicitEncryptionOnlyTour.scala 驾驶员源代码Github 存储库中的文件。

...
val clientSettings = MongoClientSettings.builder()
.autoEncryptionSettings(AutoEncryptionSettings.builder()
.keyVaultNamespace(keyVaultNamespace.getFullName)
.kmsProviders(kmsProviders)
.bypassAutoEncryption(true)
.build())
.build()
val mongoClient = MongoClient(clientSettings)
...
// Explicitly encrypt a field
val encryptedFieldValue = clientEncryption.encrypt(BsonString("123456789"),
EncryptOptions("AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic").keyId(dataKeyId))
.headResult()
collection.insertOne(Document("encryptedField" -> encryptedFieldValue)).headResult()
val doc = collection.find.first().headResult()
println(doc.toJson())

后退

读取操作