> 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/transit-digitization/ja/d1-transit-api-wosuru/dtawosuru.md).

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

機密情報をやり取りするために、D1 Transit のバックエンドは標準的な JWE 形式（<https://datatracker.ietf.org/doc/html/rfc7516> ).

機密情報は暗号化前に JSON 形式でエンコードされます。

D1 Transit バックエンドは JWE に対して次の構成を使用します：

* JWE の base64url エンコードされた文字列
* "alg"（アルゴリズム）ヘッダーパラメータ： **ECDH-ES**
* "enc"（暗号化アルゴリズム）ヘッダーパラメータ： **A256GCM**
* "kid"（キー ID）ヘッダーパラメータ：受信者の EC 公開鍵に対応するキー識別子
* EC 曲線： **P-256**

#### 機密データ暗号化の例 <a href="#examples-of-sensitive-data-encryption" id="examples-of-sensitive-data-encryption"></a>

このセクションでは、JWE オブジェクト暗号化のいくつかの例を示します。

**例：** 次のパラメータでカード資格情報を暗号化するには：

| JSON フィールドのパラメータ名 | 説明            | MOC | 長さ    |
| ----------------- | ------------- | --- | ----- |
| pan               | 主口座番号         | M   | 最大19桁 |
| exp               | 有効期限（MMYY 形式） | M   | 4     |

EC 公開鍵：

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

平文データ：

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

ソースコードサンプル：

{% tabs %}
{% tab title="node-jose を使った JavaScript" %}

```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);
})();

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

{% endtab %}

{% tab title="jose4j を使った Java" %}

```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);
}
}
// 出力 : Serialized Encrypted JWE: eyJhbGciOiJFQ0RILUVTIiwiZW5jIjoiQTI1NkdDTSIsImVwayI6eyJrdHkiOiJFQyIsIngiOiJiazF2cEFyM3lyZ3REQXVIazRrRnZ1WWVOSFFlM0dYRTcwS1Z3RU4xRTJ3IiwieSI6IjU5dEhKRnBfSHJ5UWFWN1NuTjRKZTFMVmJ1MTYwTGgxS3R1cnVyZWlTNkkiLCJjcnYiOiJQLTI1NiJ9fQ..XAjvjhUrGgQ9zu9u.crUDhRWdvW6J0NbHw2rW8S1Gn9hdLxLwAtkF-FIcR3IaF2P4_VLyQsXjZ544pb83l7x6ols.jtk3rzcjl2sLQFmYZtI7sg
```

{% endtab %}

{% tab title="josekit を使った Rust" %}

```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!("cipher文データ: {}", &ciphered_data);
 
    Ok(())
}

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

{% endtab %}
{% endtabs %}

#### 機密データ復号の例 <a href="#examples-of-sensitive-data-decryption" id="examples-of-sensitive-data-decryption"></a>

このセクションでは、JWE オブジェクト復号のいくつかの例を示します。

{% tabs %}
{% tab title="node-jose を使った JavaScript" %}

```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("復号結果:", result.plaintext.toString());
})();
 
// 出力：
// Decryption result: {"pan":"1234567891234567","exp":"1223"}
```

{% endtab %}

{% tab title="jose4j を使った Java" %}

```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("復号されたペイロード: " + jwe.getPayload());
  }
}
// 出力: Decrypted payload: {"pan":"1234567891234567","exp":"1223"}
```

{% endtab %}

{% tab title="josekit を使った Rust" %}

```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!("復号されたペイロード: {}", str::from_utf8(&payload).unwrap());
 
    Ok(())
}
 
// 出力：
// 復号されたペイロード: {"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, and the optional `goal` query parameter:

```
GET https://docs.payments.thalescloud.io/transit-digitization/ja/d1-transit-api-wosuru/dtawosuru.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

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.
