---
title: Field Level Encryption from the SDK
description: The Field Level Encryption library enables encryption and
  decryption of JSON fields, to support FIPS-140-2 compliance.
pubDate: 2026-08-17T09:53:44.266Z
antora:
  editUrl: https://github.com/couchbase/docs-sdk-cxx/edit/release/1.0/modules/howtos/pages/encrypting-using-sdk.adoc
  xref: xref:1.0@cxx-sdk:howtos:encrypting-using-sdk.adoc[]
---

[Consult the llms.txt file for a full list of contents](/llms.txt)
[View original HTML](/cxx-sdk/1.0/howtos/encrypting-using-sdk.html)

# Field Level Encryption from the SDK

> The Field Level Encryption library enables encryption and decryption of JSON fields, to support FIPS-140-2 compliance. 

For a high-level overview of this feature, see [concept-docs:encryption.adoc](#concept-docs:encryption.adoc).

## [](#package)Packaging

The Couchbase Java SDK works together with the [Java Couchbase Encryption](https://github.com/couchbase/java-couchbase-encryption) library to provide support for encryption and decryption of JSON fields. This library makes use of the cryptographic algorithms available on your platform, and provides a framework for implementing your own crypto components.

> [!NOTE]
> The encryption code is packaged as an optional library and is subject to the Couchbase [License](https://www.couchbase.com/LA03012021) and [Enterprise Subscription License](https://www.couchbase.com/ESLA08042020) agreements. To use the encryption library, you have to explicitly include this dependency in your project configuration. Refer to the [dependencies section](#maven-coordinates).

## [](#requirements)Requirements

* Couchbase Java SDK version `3.0.5` or later.
* Java Couchbase Encryption version `3.0.0` or later.

## [](#maven-coordinates)Maven Coordinates

```xml
<dependency>
    <groupId>com.couchbase.client</groupId>
    <artifactId>couchbase-encryption</artifactId>
    <version>${version}</version>
</dependency>
```

See the [GitHub repository tags](https://github.com/couchbase/java-couchbase-encryption/tags) for the latest version.

### [](#optional-dependencies)Optional Dependencies

To reduce the footprint of this library, some of its dependencies are optional. Using certain features requires adding additional dependencies to your project.

HashiCorp Vault Transit integration requires [Spring Vault](https://docs.spring.io/spring-vault/docs/current/reference/html/):

```xml
<dependency>
    <groupId>org.springframework.vault</groupId>
    <artifactId>spring-vault-core</artifactId>
    <version>2.3.2</version>
</dependency>
```

## [](#configuration)Configuration

To enable Field-Level Encryption, supply a `CryptoManager` when [configuring the Java SDK's ClusterEnvironment](managing-connections.md#cluster-environment).

```java
Unresolved include directive in modules/howtos/pages/encrypting-using-sdk.adoc - include::example$EncryptingUsingSDK.java[]
```

## [](#usage)Usage

Two modes of operation are available:

* Transparent encryption/decryption during Jackson data binding.
* Manual field editing using `JsonObjectCrypto`.

### [](#data-binding-example)Data Binding Example

Sensitive fields of your data classes can be annotated with `@Encrypted`. Let's use this class as an example:

```java
Unresolved include directive in modules/howtos/pages/encrypting-using-sdk.adoc - include::example$EncryptingUsingSDK.java[]
```

Now let's create an employee record and save it to Couchbase:

```java
Unresolved include directive in modules/howtos/pages/encrypting-using-sdk.adoc - include::example$EncryptingUsingSDK.java[]
```

You can get the document as a `JsonObject` to verify the field was encrypted:

```java
Unresolved include directive in modules/howtos/pages/encrypting-using-sdk.adoc - include::example$EncryptingUsingSDK.java[]
```

Because `contentAsObject()` does not decrypt anything, the expected output is something like:

```json
{
  "encrypted$replicant": {
    "alg": "AEAD_AES_256_CBC_HMAC_SHA512",
    "ciphertext": "xwcxyUyZ.....",
    "kid": "myKey"
  }
}
```

Now let's read the employee record using data binding:

```java
Unresolved include directive in modules/howtos/pages/encrypting-using-sdk.adoc - include::example$EncryptingUsingSDK.java[]
```

This prints `true`.

#### [](#using-a-custom-objectmapper)Using a custom ObjectMapper

The code that enables encryption/decryption during data binding is packaged as a Jackson module called `EncryptionModule`. You can register this module with any Jackson `ObjectMapper`.

You'll need to do this if you want to supply your own customized ObjectMapper for the Java SDK to use when serializing documents. Here's how to configure the cluster environment to use a custom JSON serializer backed by your own ObjectMapper with support for Field-Level Encryption:

```java
Unresolved include directive in modules/howtos/pages/encrypting-using-sdk.adoc - include::example$EncryptingUsingSDK.java[]
```

### [](#jsonobjectcrypto)JsonObjectCrypto

If you need more control of which fields get decrypted, or if you prefer working with the Couchbase `JsonObject` tree model, you can use a `JsonObjectCrypto` instance to read and write encrypted field values of a `JsonObject`.

```java
Unresolved include directive in modules/howtos/pages/encrypting-using-sdk.adoc - include::example$EncryptingUsingSDK.java[]
```

### [](#reading-unencrypted-fields)Reading Unencrypted Fields

From Java SDK 3.2.1, the `@Encrypted` annotation can now be used to migrate an existing field from unencrypted to encrypted. If you annotate a field with:

```java
@Encrypted(migration = Encrypted.Migration.FROM_UNENCRYPTED)
```

then either encrypted or unencrypted values will be accepted during deserialization (without the latter causing error). See the [API docs](https://docs.couchbase.com/sdk-api/couchbase-java-client/com/couchbase/client/java/encryption/annotation/Encrypted.html).

> [!CAUTION]
> Encryption means that document fields have been authenticated. Enabling this feature bypasses that protection, and so this should only be used in strictly limited circumstances, such as the migration from an unencrypted to an encrypted field.

## [](#creating-encryption-keys)Creating Encryption Keys

The AEAD\_AES\_256\_CBC\_HMAC\_SHA512 algorithm included in this library uses encryption keys that are 64 bytes long.

Here's an example that shows how to create a Java key store file containing a suitable encryption key:

```java
Unresolved include directive in modules/howtos/pages/encrypting-using-sdk.adoc - include::example$EncryptingUsingSDK.java[]
```

And here's how to use that file to create a `Keyring` for use with Couchbase Field-Level Encryption:

```java
Unresolved include directive in modules/howtos/pages/encrypting-using-sdk.adoc - include::example$EncryptingUsingSDK.java[]
```

## [](#migration-from-sdk2)Migrating from SDK 2

> [!WARNING]
> SDK 2 cannot read fields encrypted by SDK 3\.

It's inadvisable to have both the old and new versions of your application active at the same time. The simplest way to migrate is to do an offline upgrade during a scheduled a maintenance window. For an online upgrade without downtime, consider a [blue-green deployment](https://en.wikipedia.org/wiki/Blue-green%5Fdeployment).

SDK 3 requires additional configuration to read fields encrypted by SDK 2\. The rest of this section describes how to configure Field-Level Encryption in SDK 3 for backwards compatibility with SDK 2.

### [](#configure-field-name-prefix)Changing the field name prefix

In SDK 2, the default prefix for encrypted field names was `__crypt_`. This caused problems for Couchbase Sync Gateway, which does not like field names to begin with an underscore. In SDK 3, the default prefix is `encrypted$`.

For compatibility with SDK 2, you can configure the `CryptoManager` to use the old `__crypt_` prefix:

```java
Unresolved include directive in modules/howtos/pages/encrypting-using-sdk.adoc - include::example$EncryptingUsingSDK.java[]
```

Alternatively, you can [rename the existing fields](https://forums.couchbase.com/t/replacing-field-name-prefix/28786) using a [SQL++ (formerly N1QL)](https://www.couchbase.com/products/n1ql) statement.

> [!WARNING]
> In SDK 2, only top-level fields could be encrypted. SDK 3 allows encrypting fields at any depth. If you decide to rename the existing fields, make sure to do so _before_ writing any encrypted fields below the top level, otherwise it may be difficult to rename the nested fields using a generic SQL++ statement.

### [](#configure-legacy-decrypters)Enabling decrypters for legacy algorithms

The encryption algorithms used by SDK 2 are deprecated, and are no longer used for encrypting new data. To enable decrypting fields written by SDK 2, register the legacy decrypters when configuring the `CryptoManager`:

```java
Unresolved include directive in modules/howtos/pages/encrypting-using-sdk.adoc - include::example$EncryptingUsingSDK.java[]
```

> [!NOTE]
> The legacy decrypters require a mapping function. For AES, this function accepts an encryption key name and returns the corresponding signing key name. For RSA, this function accepts a public key name and returns the corresponding private key name.