> For the complete documentation index, see [llms.txt](https://docs.payments.thalescloud.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.payments.thalescloud.io/ecom/integrate-the-d1-api/encrypt-sensitive-data.md).

# Encrypt sensitive data

To exchange sensitive information, the D1 eCom Enablement backend expects to receive (or send) sensitive data encrypted using the standard JWE format (<https://datatracker.ietf.org/doc/html/rfc7516> ).

Sensitive information is encoded in JSON format before encryption.

D1 eCom Enablement backend uses the following configuration for JWE:

* JWE base64url encoded string
* "alg" (Algorithm) header parameter: **ECDH-ES**
* "enc" (Encryption Algorithm) header parameter: **A256GCM**
* "kid" (Key ID) header parameter: Key identifier corresponding to EC public key of the recipient
* EC curve: **P-256**

### Examples of sensitive data encryption

This section provides examples for encrypting sensitive fields as a compact JWE.

#### Example: encrypt card credentials

| JSON field | Description                        | Required | Length   |
| ---------- | ---------------------------------- | -------- | -------- |
| pan        | The Primary Account Number         | Yes      | Up to 19 |
| exp        | The expiry date in the format MMYY | Yes      | 4        |

EC public key:

```json
{
    "kty": "EC",
    "kid": "ASDsL-Jx2XOkRnFtqW-QblWY-mDnQW2LgapadFx75tA",
    "crv": "P-256",
    "x": "UbInEqNbZZZ9SJptBwKTKO6qslSyuWvMkVK44Bx_d8U",
    "y": "PUxeHMNVL0VRxOYJrkHcpe6sap7IG-Are0QborZDngI"
}
```

Clear data:

```json
{
    "pan":"1234567891234567",
    "exp":"1223"
}
```

Code samples:

{% tabs %}
{% tab title="JavaScript with node-jose" %}

```javascript
const jose = require("node-jose");

const keystore = jose.JWK.createKeyStore();
const publicKey = JSON.stringify({
 "kty": "EC",
 "kid": "ASDsL-Jx2XOkRnFtqW-QblWY-mDnQW2LgapadFx75tA",
 "crv": "P-256",
 "x": "UbInEqNbZZZ9SJptBwKTKO6qslSyuWvMkVK44Bx_d8U",
 "y": "PUxeHMNVL0VRxOYJrkHcpe6sap7IG-Are0QborZDngI",
});
const fields = {
 "alg":"ECDH-ES",
 "enc":"A256GCM",
};
const payload = {
 "pan":"1234567891234567",
 "exp":"1223"
};

(async () => {
 const ecPublicJWK = await keystore.add(publicKey, 'json');
 const encryptedData = await jose.JWE.createEncrypt({ format: "compact", fields}, ecPublicJWK).update(JSON.stringify(payload)).final();
 console.log('encryptedData', encryptedData);
})();

// output : encryptedData eyJhbGciOiJFQ0RILUVTIiwiZW5jIjoiQTI1NkdDTSIsImtpZCI6IkFTRHNMLUp4MlhPa1JuRnRxVy1RYmxXWS1tRG5RVzJMZ2FwYWRGeDc1dEEiLCJlcGsiOnsia3R5IjoiRUMiLCJjcnYiOiJQLTI1NiIsIngiOiJoWGpLdmNWa3d2ZHR4M19sdnJqTmJtQkZfZW9BZjNMeGJCblBNVFJxY2JvIiwieSI6IlJHOEN5WDV5bW9oTGV0cTFhVzgzVG96UU1EaEdQbTNHNXlwZERmVy1mSlUifX0..6L__CO5yA3g4tkLY.HysY-036kmszNeXDdgP375x0NfFlobYYGoL51A5PQ4Js9y287qZZ.QFYcZCfC6JAo1-snZ6O5Cw
```

{% endtab %}

{% tab title="Java with jose4j" %}

```java
import java.security.Key;
import java.security.spec.InvalidKeySpecException;
import java.text.ParseException;

import org.jose4j.jwe.ContentEncryptionAlgorithmIdentifiers;
import org.jose4j.jwe.JsonWebEncryption;
import org.jose4j.jwe.KeyManagementAlgorithmIdentifiers;
import org.jose4j.jwk.PublicJsonWebKey;
import org.jose4j.lang.JoseException;

public class testEncryptJWE {

public static void main(String[] args) throws InvalidKeySpecException, JoseException {
	String publicKey = "{\r\n" + "    \"kty\": \"EC\",\r\n"
			+ "    \"kid\": \"ASDsL-Jx2XOkRnFtqW-QblWY-mDnQW2LgapadFx75tA\",\r\n" 
			+ "    \"crv\": \"P-256\",\r\n"
			+ "    \"x\": \"UbInEqNbZZZ9SJptBwKTKO6qslSyuWvMkVK44Bx_d8U\",\r\n"
			+ "    \"y\": \"PUxeHMNVL0VRxOYJrkHcpe6sap7IG-Are0QborZDngI\"\r\n" 
			+ "}";
	String sensitive = "{\r\n" 
			+ "    \"pan\":\"1234567891234567\",\r\n" 
			+ "    \"exp\":\"1223\"\r\n" 
			+ "}";

	PublicJsonWebKey k = PublicJsonWebKey.Factory.newPublicJwk(publicKey);
	Key key = k.getPublicKey();
	JsonWebEncryption jwe = new JsonWebEncryption();
	jwe.setPayload(sensitive);
	jwe.setAlgorithmHeaderValue(KeyManagementAlgorithmIdentifiers.ECDH_ES);
	jwe.setEncryptionMethodHeaderParameter(ContentEncryptionAlgorithmIdentifiers.AES_256_GCM);
	jwe.setKey(key);
	String serializedJwe = jwe.getCompactSerialization();
	System.out.println("Serialized Encrypted JWE: " + serializedJwe);
}
}
// output : Serialized Encrypted JWE: eyJhbGciOiJFQ0RILUVTIiwiZW5jIjoiQTI1NkdDTSIsImVwayI6eyJrdHkiOiJFQyIsIngiOiJiazF2cEFyM3lyZ3REQXVIazRrRnZ1WWVOSFFlM0dYRTcwS1Z3RU4xRTJ3IiwieSI6IjU5dEhKRnBfSHJ5UWFWN1NuTjRKZTFMVmJ1MTYwTGgxS3R1cnVyZWlTNkkiLCJjcnYiOiJQLTI1NiJ9fQ..XAjvjhUrGgQ9zu9u.crUDhRWdvW6J0NbHw2rW8S1Gn9hdLxLwAtkF-FIcR3IaF2P4_VLyQsXjZ544pb83l7x6ols.jtk3rzcjl2sLQFmYZtI7sg
```

{% endtab %}

{% tab title="Rust with josekit" %}

```rust
use josekit::{JoseError, jwe::{self, JweHeader, ECDH_ES}};
use std::str;
 
const PUBLIC_KEY: &str = "-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEUbInEqNbZZZ9SJptBwKTKO6qslSy
uWvMkVK44Bx/d8U9TF4cw1UvRVHE5gmuQdyl7qxqnsgb4Ct7RBuitkOeAg==
-----END PUBLIC KEY-----";
 
const CLEAR_DATA: &str = "{\"pan\":\"1234567891234567\",\"exp\":\"1223\"}";
 
fn main() -> Result<(), JoseError> {

    let encrypter = ECDH_ES.encrypter_from_pem(&PUBLIC_KEY)?;
    let mut header = JweHeader::new();
    header.set_algorithm("ECDH-ES");
    header.set_content_encryption("A256GCM");
    let ciphered_data = jwe::serialize_compact(CLEAR_DATA.as_bytes(), &header, &encrypter)?;
    println!("ciphered data: {}", &ciphered_data);
 
    Ok(())
}

// output: ciphered data: eyJhbGciOiJFQ0RILUVTIiwiZW5jIjoiQTI1NkdDTSIsImVwayI6eyJrdHkiOiJFQyIsImNydiI6IlAtMjU2IiwieCI6Ims5V2UxazAyaGgzeFl1UWJMWm03bDJFX3pSZTQyalVQZXFsRjBhVlZENWciLCJ5IjoiYmgtdnJVOEhUYzZpZlNSVW1TNVByVF85c0tTb0VwQVFGaC1neHY4SW9aUSJ9fQ..eHijOIFaK-t7XhuD.MixYNb6bwnI3It_ul3t2xJLv65toe9EVNoA6hmUGZFzy477XTT5F.GhmSCoCoNKlxCBUH13_D4A
```

{% endtab %}
{% endtabs %}

### Examples of sensitive data decryption

In this section you can find few examples of a JWE object decryption.

{% tabs %}
{% tab title="JavaScript with node-jose" %}

```javascript
const jose = require("node-jose");
const jwe = "eyJhbGciOiJFQ0RILUVTIiwiZW5jIjoiQTI1NkdDTSIsImtpZCI6IkFTRHNMLUp4MlhPa1JuRnRxVy1RYmxXWS1tRG5RVzJMZ2FwYWRGeDc1dEEiLCJlcGsiOnsia3R5IjoiRUMiLCJjcnYiOiJQLTI1NiIsIngiOiJoWGpLdmNWa3d2ZHR4M19sdnJqTmJtQkZfZW9BZjNMeGJCblBNVFJxY2JvIiwieSI6IlJHOEN5WDV5bW9oTGV0cTFhVzgzVG96UU1EaEdQbTNHNXlwZERmVy1mSlUifX0..6L__CO5yA3g4tkLY.HysY-036kmszNeXDdgP375x0NfFlobYYGoL51A5PQ4Js9y287qZZ.QFYcZCfC6JAo1-snZ6O5Cw";
const privateKey = "-----BEGIN EC PRIVATE KEY-----\r\nMHcCAQEEIFUvax1cOkuRkKFmypV7FtN5GR+1PjSXJ3yS0yGcn0R7oAoGCCqGSM49\r\nAwEHoUQDQgAEUbInEqNbZZZ9SJptBwKTKO6qslSyuWvMkVK44Bx/d8U9TF4cw1Uv\r\nRVHE5gmuQdyl7qxqnsgb4Ct7RBuitkOeAg==\r\n-----END EC PRIVATE KEY-----";
 
const keystore = jose.JWK.createKeyStore();
 
(async () => {
    const ecJWK = await keystore.add(privateKey, "pem");
    const result = await jose.JWE.createDecrypt(ecJWK).decrypt(jwe);
    console.log("Decryption result:", result.plaintext.toString());
})();
 
// Output:
// Decryption result: {"pan":"1234567891234567","exp":"1223"}
```

{% endtab %}

{% tab title="Java with jose4j" %}

```java
import java.security.Key;
import java.security.spec.InvalidKeySpecException;
import java.util.HashMap;
import java.util.Map;

import org.jose4j.jwe.JsonWebEncryption;
import org.jose4j.jwk.EllipticCurveJsonWebKey;
import org.jose4j.lang.JoseException;

public class testEncryptJWE {
public static void main(String[] args) throws InvalidKeySpecException, JoseException {
	Map<String, Object> privateKey = new HashMap<String, Object>();
	privateKey.put("x", "UbInEqNbZZZ9SJptBwKTKO6qslSyuWvMkVK44Bx_d8U");
	privateKey.put("y", "PUxeHMNVL0VRxOYJrkHcpe6sap7IG-Are0QborZDngI");
	privateKey.put("d", "VS9rHVw6S5GQoWbKlXsW03kZH7U-NJcnfJLTIZyfRHs");
	privateKey.put("crv", "P-256");
	privateKey.put("kid", "ASDsL-Jx2XOkRnFtqW-QblWY-mDnQW2LgapadFx75tA");

	EllipticCurveJsonWebKey k = new EllipticCurveJsonWebKey(privateKey);
	Key key = k.getEcPrivateKey();
	String cipheredData = "eyJhbGciOiJFQ0RILUVTIiwiZW5jIjoiQTI1NkdDTSIsImtpZCI6IkFTRHNMLUp4MlhPa1JuRnRxVy1RYmxXWS1tRG5RVzJMZ2FwYWRGeDc1dEEiLCJlcGsiOnsia3R5IjoiRUMiLCJjcnYiOiJQLTI1NiIsIngiOiJoWGpLdmNWa3d2ZHR4M19sdnJqTmJtQkZfZW9BZjNMeGJCblBNVFJxY2JvIiwieSI6IlJHOEN5WDV5bW9oTGV0cTFhVzgzVG96UU1EaEdQbTNHNXlwZERmVy1mSlUifX0..6L__CO5yA3g4tkLY.HysY-036kmszNeXDdgP375x0NfFlobYYGoL51A5PQ4Js9y287qZZ.QFYcZCfC6JAo1-snZ6O5Cw";
	JsonWebEncryption jwe = new JsonWebEncryption();
	jwe.setKey(key);
	jwe.setCompactSerialization(cipheredData);
	System.out.println("Decrypted payload: " + jwe.getPayload());
  }
}
// output: Decrypted payload: {"pan":"1234567891234567","exp":"1223"}
```

{% endtab %}

{% tab title="Rust with josekit" %}

```rust
use josekit::{JoseError, jwe::{self, ECDH_ES}};
use std::str;
 
const PRIVATE_KEY: &str = "-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIFUvax1cOkuRkKFmypV7FtN5GR+1PjSXJ3yS0yGcn0R7oAoGCCqGSM49
AwEHoUQDQgAEUbInEqNbZZZ9SJptBwKTKO6qslSyuWvMkVK44Bx/d8U9TF4cw1Uv
RVHE5gmuQdyl7qxqnsgb4Ct7RBuitkOeAg==
-----END EC PRIVATE KEY-----";
 
const JWE_FROM_SAMPLE: &str = "eyJhbGciOiJFQ0RILUVTIiwiZW5jIjoiQTI1NkdDTSIsImtpZCI6IkFTRHNMLUp4MlhPa1JuRnRxVy1RYmxXWS1tRG5RVzJMZ2FwYWRGeDc1dEEiLCJlcGsiOnsia3R5IjoiRUMiLCJjcnYiOiJQLTI1NiIsIngiOiJoWGpLdmNWa3d2ZHR4M19sdnJqTmJtQkZfZW9BZjNMeGJCblBNVFJxY2JvIiwieSI6IlJHOEN5WDV5bW9oTGV0cTFhVzgzVG96UU1EaEdQbTNHNXlwZERmVy1mSlUifX0..6L__CO5yA3g4tkLY.HysY-036kmszNeXDdgP375x0NfFlobYYGoL51A5PQ4Js9y287qZZ.QFYcZCfC6JAo1-snZ6O5Cw";
 
fn main() -> Result<(), JoseError> {
    let decrypter = ECDH_ES.decrypter_from_pem(&PRIVATE_KEY)?;
    let (payload, _) = jwe::deserialize_compact(&JWE_FROM_SAMPLE, &decrypter)?;
    println!("Decrypted payload: {}", str::from_utf8(&payload).unwrap());
 
    Ok(())
}
 
// Output:
// Decrypted payload: {"pan":"1234567891234567","exp":"1223"}
```

{% endtab %}
{% endtabs %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.payments.thalescloud.io/ecom/integrate-the-d1-api/encrypt-sensitive-data.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
