> 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/transaction-control/ja/integrate-the-d1-api/encrypt-sensitive-data.md).

# 機密データを暗号化する

Encrypt sensitive fields exchanged with the D1 backend using JSON Web Encryption (JWE) ([RFC 7516](https://datatracker.ietf.org/doc/html/rfc7516)).

Serialize the sensitive fields as JSON before you encrypt.

### JWE requirements

Use JWE compact serialization (a single Base64URL-encoded string).

The D1 backend expects the following JWE configuration:

* `alg`: `ECDH-ES`
* `enc`: `A256GCM`
* `kid`: key identifier of the recipient public key
* EC curve: `P-256`

{% hint style="info" %}
Set `kid` to the identifier of the public key you provisioned for the recipient. The D1 backend uses `kid` to select the correct key.
{% endhint %}

### Encrypt sensitive data

This section shows an end-to-end example that encrypts card credentials for the D1 backend.

#### Example payload

Encrypt the following JSON fields:

| JSON field | Description          | MOC | Length   |
| ---------- | -------------------- | --- | -------- |
| `pan`      | PAN                  | M   | Up to 19 |
| `exp`      | Expiry date (`MMYY`) | M   | 4        |

Recipient EC public key (JWK):

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

Clear data (JSON to encrypt):

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

Source 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 Nimbus-JOSE-JWT" %}

```java
import java.text.ParseException;

import com.nimbusds.jose.EncryptionMethod;
import com.nimbusds.jose.JOSEException;
import com.nimbusds.jose.JWEAlgorithm;
import com.nimbusds.jose.JWEEncrypter;
import com.nimbusds.jose.JWEHeader;
import com.nimbusds.jose.JWEObject;
import com.nimbusds.jose.Payload;
import com.nimbusds.jose.crypto.ECDHEncrypter;
import com.nimbusds.jose.jwk.ECKey;

public class testEncryptJWE {

public static void main(String[] args) throws JOSEException, ParseException {		
	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"
			+ "}";
	ECKey pubK = ECKey.parse(publicKey);
	JWEEncrypter encrypter = new ECDHEncrypter(pubK);

	JWEHeader header = new JWEHeader.Builder(JWEAlgorithm.ECDH_ES, EncryptionMethod.A256GCM)
			.keyID("ASDsL-Jx2XOkRnFtqW-QblWY-mDnQW2LgapadFx75tA").build();

	String sensitive  = "{\r\n"
			+ "    \"pan\":\"1234567891234567\",\r\n"
			+ "    \"exp\":\"1223\"\r\n"
			+ "}";
	JWEObject jwe = new JWEObject(header, new Payload(sensitive));
	jwe.encrypt(encrypter);
	String jweString = jwe.serialize();
	System.out.println(jweString);
}
}
// output : eyJlcGsiOnsia3R5IjoiRUMiLCJjcnYiOiJQLTI1NiIsIngiOiJSN1ZYSUU4RWNCRlJnbmJOTjlaejRMSEo5NHJrVmlkY1luUHIwWkVON3c0IiwieSI6IkJMUm9CQ0NWYXVYU21mLWI4Q2VWclc4YVJpNmtDa0VZOHZ1OEVSR04wTDAifSwia2lkIjoiQVNEc0wtSngyWE9rUm5GdHFXLVFibFdZLW1EblFXMkxnYXBhZEZ4NzV0QSIsImVuYyI6IkEyNTZHQ00iLCJhbGciOiJFQ0RILUVTIn0..213CBfhxvccNu9QE.IwcTKsZHYYoSLcHDVSFKbj83YfyZVR42WpynetTivLbsz65ap7HxcJb8GSnb4uuMuF-P3D0.vkq8jkQU4r_1UIT2RzQ6jQ
```

{% 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 %}

### Decrypt sensitive data

Decrypt the JWE payload in your issuer backend using the matching private key.

{% 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="Javascript without dependencies" %}

```javascript
const crypto = require("crypto");
 
// Warning: keydatalen is in bytes, not in bits!
function concatKDFSHA256(z, keydatalen, otherInfo) {
    const reps = Math.ceil(keydatalen / 32); // 32 bytes in the size oh SHA256's output
    let counter = 1;
 
    const Ks = [];
    for (let i = 0; i < reps; i++) {
        const counterAsUInt32BE = Buffer.alloc(4);
        counterAsUInt32BE.writeUInt32BE(counter);
        const dataToHash = Buffer.concat([counterAsUInt32BE, z, otherInfo]);
        const Ki = crypto.createHash("sha256").update(dataToHash).digest();
        Ks.push(Ki);
        counter++;
    }
 
    const remainingBytes = keydatalen % 32;
    if (remainingBytes !== 0) {
        Ks[reps - 1] = Ks[reps - 1].slice(0, remainingBytes);
    }
 
    return Buffer.concat(Ks).slice(0, keydatalen);
}
 
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 [jweHeader, jweEncryptedKey, jweIv, jweCiphertext, jweAuthenticationTag] = jwe.split(".");
 
const decodedHeader = JSON.parse(Buffer.from(jweHeader, "base64").toString("utf8"));
console.log("JWE header:", JSON.stringify(decodedHeader));
 
const sharedSecret = crypto.diffieHellman({
    privateKey: crypto.createPrivateKey(privateKey),
    publicKey: crypto.createPublicKey({
        key: decodedHeader.epk,
        format: "jwk"
    })
})
 
const algorithmIdData = Buffer.from(decodedHeader.enc, "ascii");
const algorithmIdDataLength = Buffer.alloc(4);
algorithmIdDataLength.writeUInt32BE(algorithmIdData.length);
const algorithmId = Buffer.concat([algorithmIdDataLength, algorithmIdData]);
 
const partyUInfo = Buffer.from([0, 0, 0, 0]);
const partyVInfo = Buffer.from([0, 0, 0, 0]);
 
const suppPubInfo = Buffer.alloc(4);
suppPubInfo.writeUInt32BE(256); // 256 = keydatalen in bits
 
const otherInfo = Buffer.concat([algorithmId, partyUInfo, partyVInfo, suppPubInfo]);
 
const derivedKey = concatKDFSHA256(sharedSecret, 32, otherInfo);
 
const iv = Buffer.from(jweIv, "base64");
const ciphertext = Buffer.from(jweCiphertext, "base64");
const authTag = Buffer.from(jweAuthenticationTag, "base64");
 
const decipher = crypto.createDecipheriv("aes-256-gcm", derivedKey, iv);
const clearText = decipher.update(ciphertext).toString();
console.log("Clear text:", clearText);
 
// Output:
// JWE header: {"alg":"ECDH-ES","enc":"A256GCM","kid":"ASDsL-Jx2XOkRnFtqW-QblWY-mDnQW2LgapadFx75tA","epk":{"kty":"EC","crv":"P-256","x":"hXjKvcVkwvdtx3_lvrjNbmBF_eoAf3LxbBnPMTRqcbo","y":"RG8CyX5ymohLetq1aW83TozQMDhGPm3G5ypdDfW-fJU"}}
// Clear text: {"pan":"1234567891234567","exp":"1223"}
```

{% endtab %}

{% tab title="Java with Nimbus-JOSE-JWT" %}

```java
import java.text.ParseException;

import com.nimbusds.jose.JOSEException;
import com.nimbusds.jose.JWEDecrypter;
import com.nimbusds.jose.JWEObject;
import com.nimbusds.jose.crypto.ECDHDecrypter;
import com.nimbusds.jose.jwk.ECKey;

public class testEncryptJWE {
	
public static void main(String[] args) throws JOSEException, ParseException {
		
	String cipheredData = "eyJhbGciOiJFQ0RILUVTIiwiZW5jIjoiQTI1NkdDTSIsImtpZCI6IkFTRHNMLUp4MlhPa1JuRnRxVy1RYmxXWS1tRG5RVzJMZ2FwYWRGeDc1dEEiLCJlcGsiOnsia3R5IjoiRUMiLCJjcnYiOiJQLTI1NiIsIngiOiJoWGpLdmNWa3d2ZHR4M19sdnJqTmJtQkZfZW9BZjNMeGJCblBNVFJxY2JvIiwieSI6IlJHOEN5WDV5bW9oTGV0cTFhVzgzVG96UU1EaEdQbTNHNXlwZERmVy1mSlUifX0..6L__CO5yA3g4tkLY.HysY-036kmszNeXDdgP375x0NfFlobYYGoL51A5PQ4Js9y287qZZ.QFYcZCfC6JAo1-snZ6O5Cw";
	String privateKey = "{\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"
			+ "  \"d\": \"VS9rHVw6S5GQoWbKlXsW03kZH7U-NJcnfJLTIZyfRHs\"       \r\n"
			+ "}";
	JWEObject j = JWEObject.parse(cipheredData);
	JWEDecrypter decrypter = new ECDHDecrypter(ECKey.parse(privateKey));
	j.decrypt(decrypter);
	System.out.println("Decrypted payload: " + j.getPayload().toString());
}
}
// output: Decrypted payload: {"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 %}

### Generate a P-256 key pair

Use OpenSSL to generate a P-256 key pair for JWE encryption and decryption.

Generate a private key for your issuer backend. Protect it in your environment.

```
openssl ecparam -name prime256v1 -genkey -noout -out issuerId-jwe-priv-key.pem
```

Generate a public key to provision in the D1 backend.

```
openssl ec -in issuerId-jwe-priv-key.pem -pubout > issuerId-jwe-pub-key.pem
```

Keep the private key in your issuer backend to decrypt payloads sent by the D1 backend.

Provide the public key and its `kid` to the Thales Delivery Team during D1 Onboarding. The D1 backend uses the public key to encrypt sensitive data for your issuer backend.


---

# 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/transaction-control/ja/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.
