클라이언트 측 암호화
이 페이지의 내용
v4.2 부터 시작됩니다. MongoDB는 클라이언트 사이드 암호화를 지원합니다. 클라이언트 사이드 암호화를 통해 관리자와 개발자는 다른 MongoDB 암호화 기능을 제공할 뿐만 아니라 특정 데이터 필드를 암호화할 수 있습니다.
필드 수준 암호화를 사용하면 개발자는 서버 사이드 구성이나 지시문 없이 클라이언트 사이드에서 필드를 암호화할 수 있습니다. 클라이언트 사이드 필드 수준 암호화는 서버 관리자를 포함한 권한이 없는 당사자가 암호화된 데이터를 읽을 수 없도록 애플리케이션이 보장해야 하는 워크로드를 지원합니다.
참고
이 가이드 에서는 퀵 스타트 프라이머에서 다루는 Observable
암시를 사용합니다.
설치
프로젝트에서 필드 수준 암호화를 사용하여 시작하는 데 권장되는 방법은 종속성 관리 시스템을 사용하는 것입니다. 필드 수준 암호화에는 드라이버 외에 추가 패키지가 필요합니다.
참고
Scala 드라이버를 설치하는 방법에 대한 지침은 설치 가이드를 참조하세요.
libmongocrypt
libmongocrypt
바인딩이 포함된 별도의 JAR 파일이 있습니다.
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' }
mongocryptd 구성
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 cluster, 모든 사용자에 대해 자동 암호 해독이 지원됩니다. 자동 자동 암호화 해독을 구성하려면 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())