Key Management Service のユースケース

Prev Next

Classic/VPC環境で利用できます。

Key Management Serviceを利用してエンベロープ暗号化(Envelope Encryption)を実装するユースケースを紹介します。

注意

Key Management Serviceのユースケースで紹介するコードは、Key Management Serviceに対する理解を助けるために作成した仮想のシナリオです。例外処理などの作業に不備があり、実際のシナリオに完璧に対応できないので、実際の状況にこのまま適用しないようにご注意ください。

機密情報のエンベロープ暗号化

機密情報のエンベロープ暗号化に関するシナリオとユースケースについて説明します。

シナリオ

NAVERクラウドプラットフォームを使用中のウェブサービス会社のサーバ開発者 Aは、ウェブサーバで DBサーバにアクセスするための DB認証情報を暗号化するという、以下の要求事項を受け付けました。

  • DB認証情報は暗号化して保護される必要がある
  • すべての暗号化キーは標準勧告レベルで適切に作成、運用、保護される必要がある

そのため、DB認証情報をデータ暗号化キー(DEK)で暗号化し、DEKも他のキーで暗号化して保管することにしました。データキーを暗号化する上位キーのマスターキー(KEK)を利用するために、Key Management Serviceのキーアクセス権を申し込みました。DEKの暗号化/復号化が必要なため、Key Management Serviceキーに対する Change/encrypt、Change/decryptと View/getKeyInfo、View/getKeyList の権限を付与された後、コンソールを通じてキー Tagを確認しました。
Aは、既に Sub Accountを通じて知っていた Access keyと Secret keyを、NAVERクラウドプラットフォームコンソールの Sub Accountにアクセスしてもう一度確認しました。その後にこれらをそれぞれ NCP_ACCESS_KEYNCP_SECRET_KEYという名前で環境変数として設定しました。
また、Key Management Service APIを直接呼び出すために API Gatewayの API Keysで Key Management Service専用の API keyを確認して存在しないことを確認し、アカウント管理者に Key Management Service専用の API key作成をリクエストしました。アカウント管理者から、Key Management Service APIは汎用の API keyを使用しても構わないという確認を受け、汎用の API keyを自分の開発環境システムに NCP_API_KEYという名前の環境変数として設定しました。
DEKもまた暗号化作成推奨基準を守りたかった Aは、Key Management Serviceの createCustomKey APIを通じて複雑なキー作成を直接行う必要がなく、high-entropyキーを作成できることに気づきました。
DB認証情報の暗号化には AES-CBCを利用するので、暗号化/復号化に利用される追加情報の IV(Initial Vector)の値も一緒に管理する必要があります。そこで Aは、DB認証情報とデータキー、追加暗号化情報を以下のようなエンベロープ形式のデータで管理することにしました。

{
  "ciphertext": "暗号化された DB認証情報",
  "wrappedKey": "暗号化されたデータ暗号化キー",
  "iv": "暗号化に使用する追加情報 例) IV値"
}

サンプルコード

クレデンシャルのエンベロープ暗号化シナリオに従って Javaで作成したエンベロープ暗号化作成のユースケースは、次の通りです。

public class EncryptCredential {

  // URI
  private static String KMS_API_BASE_URI = "https://kms.apigw.ntruss.com";

  // END POINT
  private static String KMS_API_DECRYPT = "/keys/v1/%s/decrypt"; // Change/decrypt権限必要(KMS API stage v1を使用)
  //private static String KMS_API_DECRYPT = "/keys/v2/%s/decrypt"; // Change/decrypt権限必要(KMS API stage v2を使用)
  private static String KMS_API_CUSTOM_KEY = "/keys/v1/%s/createCustomKey"; // Change/encrypt権限必要(KMS API stage v1を使用)
  //private static String KMS_API_CUSTOM_KEY = "/keys/v2/%s/createCustomKey"; // Change/encrypt権限必要(KMS API stage v2を使用)

  // サンプル用 KEY TAG
  private static String KEY_TAG = "4165867476e68eca06e84c993708c23d22ca2cb6a51ac15750bd7e991ccadc39";

  private static String ncpAccessKey;
  private static String ncpSecretKey;
  private static String ncpApiKey;

  public static void main(String[] args) throws Exception {
    // API認証情報をシステム環境変数に登録して使用
    ncpAccessKey = System.getenv("NCP_ACCESS_KEY");
    ncpSecretKey = System.getenv("NCP_SECRET_KEY");
    ncpApiKey = System.getenv("NCP_API_KEY");

    envelopCredential();
  }

  public static void envelopCredential() throws Exception {
    // 新しい high-entropyデータキーの作成をリクエスト
    String wrappedDataKey = getCustomKey();
    // 最終的に保護したい機密データ
    String example_credential_json = "{\"AUTH\":\"THIS_IS_A_DB_CREDENTIAL\"}}";

    // ユーザーが保管する暗号化されたデータエンベロープ(Envelop encryptionを参照)
    String envelope = encrypt(example_credential_json, wrappedDataKey);
    // このサンプルコードでは、暗号化されたデータエンベロープをファイルに保存
    File envelopeFile = new File("credentialEnvelope.json");
    OutputStream os = new BufferedOutputStream(new FileOutputStream(envelopeFile));

    try {
      os.write(envelope.getBytes());
    } finally {
      os.close();
    }
  }

  private static String encrypt(Object obj, String wrappedDataKey) throws Exception {
    Map<String, String> envelope = new HashMap<>();

    // データキー unwrapping
    String dataKey = unwrapKey(wrappedDataKey);

    // 作成された high-enrtopy 256 bitのデータキーを AES-CBC方式で暗号化
    SecretKey secretKey = new SecretKeySpec(decodeFromBase64(dataKey),"AES");
    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
    cipher.init(Cipher.ENCRYPT_MODE, secretKey);
    byte[] iv = cipher.getParameters().getParameterSpec(IvParameterSpec.class).getIV();
    byte[] ciphertext = cipher.doFinal(obj.toString().getBytes());

    envelope.put("wrappedKey", wrappedDataKey);
    envelope.put("ciphertext", encodeToBase64(ciphertext));
    envelope.put("iv", encodeToBase64(iv));

    return JSONValue.toJSONString(envelope);
  }

  private static String unwrapKey(String sealedKey) throws Exception {
    String endPoint = String.format(KMS_API_DECRYPT, KEY_TAG);

    JSONObject data = new JSONObject();
    data.put("ciphertext", sealedKey);
    JSONObject respJsonObject = apiCaller(endPoint, data.toJSONString());
    String plaintext = (respJsonObject.get("plaintext")).toString();
    return plaintext;
  }

  private static String getCustomKey() throws Exception {
    String endPoint = String.format(KMS_API_CUSTOM_KEY, KEY_TAG);

    JSONObject data = new JSONObject();
    data.put("requestPlainKey", false);
    JSONObject respJsonObject = apiCaller(endPoint, data.toJSONString());
    return respJsonObject.get("ciphertext").toString();
  }

  private static JSONObject apiCaller(String endPoint, String data) throws Exception {
    HttpClient client = HttpClients.createDefault();

    long timestamp = System.currentTimeMillis();
    String signature = makeSignature(endPoint, timestamp);
    URIBuilder uriBuilder = new URIBuilder(KMS_API_BASE_URI);
    uriBuilder.setPath(endPoint);

    HttpPost request = new HttpPost(uriBuilder.build().toString());
    request.addHeader("x-ncp-apigw-timestamp", timestamp + "");
    request.addHeader("x-ncp-apigw-api-key", ncpApiKey); // v1を使用する場合に必要
    //request.addHeader("x-ncp-apigw-api-key", ncpApiKey); // v2を使用する場合に不要
    request.addHeader("x-ncp-iam-access-key", ncpAccessKey);
    request.addHeader("x-ncp-apigw-signature-v1", signature);
    request.addHeader("Content-Type", "application/json");
    request.setEntity(new StringEntity(data));

    HttpResponse response = client.execute(request);
    String responseBody = EntityUtils.toString(response.getEntity());
    JSONParser parser = new JSONParser();
    JSONObject repsObj = (JSONObject) parser.parse(responseBody);
    JSONObject dataObj = (JSONObject) repsObj.get("data");
    return dataObj;
  }

  private static String encodeToBase64(byte[] bytesToEncode) {
    return Base64.getEncoder().encodeToString(bytesToEncode);
  }

  private static byte[] decodeFromBase64(String stringToDecode) {
    return Base64.getDecoder().decode(stringToDecode);
  }

  // API Gateway認証用 API呼び出しシグネチャーの作成(API Gatewayご利用ガイドを参照)
  private static String makeSignature(String uri , long timestamp) throws Exception {
    String message = new StringBuilder()
      .append("POST").append(" ").append(uri).append("\n")
      .append(timestamp).append("\n")
      .append(ncpApiKey).append("\n") // v1を使用する場合に必要
      //.append(ncpApiKey).append("\n") // v2を使用する場合に不要
      .append(ncpAccessKey)
      .toString();

    SecretKeySpec signingKey = new SecretKeySpec(ncpSecretKey.getBytes("UTF-8"), "HmacSHA256");
    Mac mac = Mac.getInstance("HmacSHA256");
    mac.init(signingKey);
    byte[] rawHmac = mac.doFinal(message.getBytes("UTF-8"));
    String encodeBase64String = Base64.getEncoder().encodeToString(rawHmac);
    return encodeBase64String;
  }

}

作成結果

サンプルコードの作成結果は次の通りです。

{
  "ciphertext":"wh6wryZ5MUrzlzd7EW9OYNek+3taxNVnxAcUPBRR6vtDH29tDrFxLyNukqUT3s7i",
  "iv":"HDlrArTVqwHQJRx9IhtqzQ==",
  "wrappedKey":"ncpkms:v1:e0AGESFjKj7xFtCxW1zfGFyZ3G\/4mc51mAMMu1n2hHNLsI4X9h5NKRKx0avz+1ky7\/+7aCd5SAjCOlnV"
}

暗号化されたエンベロープ(Envelope)を使用する

暗号化されたエンベロープ(Envelope)の使用をサポートするための仮想シナリオとサンプルコードを紹介します。

シナリオ

機密情報のエンベロープ暗号化シナリオを通じて暗号化処理した DB認証情報が含まれたエンベロープを、実際のサーバコードで利用します。これをテストするために、開発者 Aは DBアクセス前にエンベロープの暗号文を復号化して DB認証情報に変換するコードを作成します。

サンプルコード

暗号化されたエンベロープ(Envelope)の使用シナリオに従って Javaで作成したユースケースは、次の通りです。

public class ClientApiSample {

  // URI
  private static String KMS_API_BASE_URI = "https://kms.apigw.ntruss.com";

  // END POINT
  private static String KMS_API_DECRYPT = "/keys/v1/%s/decrypt"; // Change/decrypt権限必要(KMS API stage v1を使用)
  //private static String KMS_API_DECRYPT = "/keys/v2/%s/decrypt"; // Change/decrypt権限必要(KMS API stage v2を使用)

  // KEY TAG
  private static String KEY_TAG = "1bc86ca1be3b062cf8503d0a7e6d3717fe3a1c0480e309b724b26bf961e1f3c6";

  private static String ncpAccessKey;
  private static String ncpSecretKey;
  private static String ncpApiKey;

  public static void main(String[] args) throws Exception {
    // API認証情報をシステム環境変数に登録して使用
    ncpAccessKey = System.getenv("NCP_ACCESS_KEY");
    ncpSecretKey = System.getenv("NCP_SECRET_KEY");
    ncpApiKey = System.getenv("NCP_API_KEY");

    String dbCredential = getCredential();
  }

  public static String getCredential() throws Exception {
    // ユーザーが保管する暗号化されたデータエンベロープ(Envelop encryptionを参照)
    File envelopeFile = new File("credentialEnvelope.json");
    InputStream is = new BufferedInputStream(new FileInputStream(envelopeFile));

    String envelope = new String(Files.readAllBytes(Paths.get("credentialEnvelope.json")));
    JSONParser parser = new JSONParser();
    JSONObject envelopeJson = (JSONObject) parser.parse(envelope);
    String wrappedDataKey = envelopeJson.get("wrappedKey").toString();
    String ciphertext = envelopeJson.get("ciphertext").toString();
    String iv = envelopeJson.get("iv").toString();

    return decrypt(ciphertext, wrappedDataKey, iv);
  }

  private static String decrypt(String ciphertext, String wrappedDataKey, String iv) throws Exception {

    String dataKey = unwrapKey(wrappedDataKey);
    IvParameterSpec ivParameterSpec = new IvParameterSpec(decodeFromBase64(iv));
    SecretKey secretKey = new SecretKeySpec(decodeFromBase64(dataKey), "AES");
    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
    cipher.init(Cipher.DECRYPT_MODE, secretKey, ivParameterSpec);
    byte[] plaintext = cipher.doFinal(decodeFromBase64(ciphertext));

    return new String(plaintext);
  }

  private static String unwrapKey(String sealedKey) throws Exception {
    String endPoint = String.format(KMS_API_DECRYPT, KEY_TAG);

    JSONObject data = new JSONObject();
    data.put("ciphertext", sealedKey);
    JSONObject respJsonObject = apiCaller(endPoint, data.toJSONString());
    String plaintext = (respJsonObject.get("plaintext")).toString();
    return plaintext;
  }

  private static JSONObject apiCaller(String endPoint, String data) throws Exception {
    HttpClient client = HttpClients.createDefault();

    long timestamp = System.currentTimeMillis();
    String signature = makeSignature(endPoint, timestamp);
    URIBuilder uriBuilder = new URIBuilder(KMS_API_BASE_URI);
    uriBuilder.setPath(endPoint);

    HttpPost request = new HttpPost(uriBuilder.build().toString());
    request.addHeader("x-ncp-apigw-timestamp", timestamp + "");
    request.addHeader("x-ncp-apigw-api-key", ncpApiKey); // v1を使用する場合に必要
    //request.addHeader("x-ncp-apigw-api-key", ncpApiKey); // v2を使用する場合に不要
    request.addHeader("x-ncp-iam-access-key", ncpAccessKey);
    request.addHeader("x-ncp-apigw-signature-v1", signature);
    request.addHeader("Content-Type", "application/json");
    request.setEntity(new StringEntity(data));

    HttpResponse response = client.execute(request);
    String responseBody = EntityUtils.toString(response.getEntity());
    JSONParser parser = new JSONParser();
    JSONObject repsObj = (JSONObject) parser.parse(responseBody);
    JSONObject dataObj = (JSONObject) repsObj.get("data");
    return dataObj;
  }

  private static byte[] decodeFromBase64(String stringToDecode) {
    return Base64.getDecoder().decode(stringToDecode);
  }

  // API Gateway認証用 API呼び出しシグネチャーの作成(API Gatewayご利用ガイドを参照)
  private static String makeSignature(String uri , long timestamp) throws Exception {
    String message = new StringBuilder()
      .append("POST").append(" ").append(uri).append("\n")
      .append(timestamp).append("\n")
      .append(ncpApiKey).append("\n") // v1を使用する場合に必要
      //.append(ncpApiKey).append("\n") // v2を使用する場合に不要
      .append(ncpAccessKey)
      .toString();

    SecretKeySpec signingKey = new SecretKeySpec(ncpSecretKey.getBytes("UTF-8"), "HmacSHA256");
    Mac mac = Mac.getInstance("HmacSHA256");
    mac.init(signingKey);
    byte[] rawHmac = mac.doFinal(message.getBytes("UTF-8"));
    String encodeBase64String = Base64.getEncoder().encodeToString(rawHmac);
    return encodeBase64String;
  }

}

データ暗号化キー管理

データ暗号化キー(DEK)管理の理解を助けるための仮想シナリオとサンプルコードを紹介します。

シナリオ

機密情報と DEKを暗号化して一緒にまとめて保管する方式は、データ保護において最も安全だと知られている方式です。ただし、これがすべてではありません。すべての暗号化キーは、知られている暗号学的脆弱性に備えるために、定期的なローテーション(更新)が必要です。
先ほど紹介したサンプルコードで KEY_TAGで利用したマスターキーは、一定周期(最大365日)で自動ローテーションされるように必須設定されています。それだけではなく、Key Management Service管理者(またはキー管理者)により手動でローテーションを行うこともできます。
開発者 Aが DB認証情報の暗号化に直接利用していた DEKはマスターキーで暗号化されているため、マスターキーがローテーションされたら暗号化した DEKをローテーションされた新しいマスターキーで再暗号化する必要があります。再暗号化は Key Management Serviceの reencrypt APIを利用して簡単に行えます。reencrypt APIは、最も最新バージョンのキーで既存暗号文を再暗号化します。
Aは、キーの使用権限が割り当てられる際にメールで通知を受けたように、キーがローテーションされるとそれに対する通知も受け取ることになります。通知を受け取ったら、できるだけ早く再暗号化を行う必要があります。これのために Aは、キーローテーションの通知を受け取ると実行するコードを以下のように作成しました。これから DEKは、ローテーションされた新しいバージョンで再暗号化され、新しいエンベロープを作成することになります。再暗号化後には既存のエンベロープを削除することが安全です。ただし、データの消失を防ぐために、再暗号化したエンベロープを直接確認してから削除することをお勧めします。したがって、既存のエンベロープを直ちに上書きせずに、新しいエンベロープを作成して確認してから削除する方式に行いたいです。

サンプルコード

DEK管理シナリオに従って Javaで作成したユースケースは、次の通りです。

public class ClientApiSample {

  // URI
  private static String KMS_API_BASE_URI = "https://kms.apigw.ntruss.com";

  // END POINT
  private static String KMS_API_REENCRYPT = "/keys/v1/%s/reencrypt"; // KMS API stage v1を使用
  // private static String KMS_API_REENCRYPT = "/keys/v2/%s/reencrypt"; // KMS API stage v2を使用

  // KEY TAG
  private static String KEY_TAG = "1bc86ca1be3b062cf8503d0a7e6d3717fe3a1c0480e309b724b26bf961e1f3c6";

  private static String ncpAccessKey;
  private static String ncpSecretKey;
  private static String ncpApiKey;

  public static void main(String[] args) throws Exception {
    ncpAccessKey = System.getenv("NCP_ACCESS_KEY");
    ncpSecretKey = System.getenv("NCP_SECRET_KEY");
    ncpApiKey = System.getenv("NCP_API_KEY");

    reenvelopCredential();
  }

  private static void reenvelopCredential() throws Exception {
    String envelope = new String(Files.readAllBytes(Paths.get("credentialEnvelope.json")));
    JSONParser parser = new JSONParser();
    JSONObject envelopeJson = (JSONObject) parser.parse(envelope);
    String wrappedDataKey = envelopeJson.get("wrappedKey").toString();
    String ciphertext = envelopeJson.get("ciphertext").toString();
    String iv = envelopeJson.get("iv").toString();

    // 暗号化されたデータキーを最新バージョンに再暗号化
    String rewrappedDataKey = rewrapKey(wrappedDataKey);

    Map<String, String> newEnvelope = new HashMap<>();
    // 暗号文と ivは変更せず、再暗号化されたキーのみ変更
    newEnvelope.put("wrappedKey", rewrappedDataKey);
    newEnvelope.put("ciphertext", ciphertext);
    newEnvelope.put("iv", iv);

    String newEnvelopeJson = JSONValue.toJSONString(newEnvelope);

    // 新しいエンベロープ作成(確認後に既存のエンベロープの削除が必要)
    File newEnvelopeFile = new File("credentialEnvelope_new.json");
    OutputStream os = new BufferedOutputStream(new FileOutputStream(newEnvelopeFile));

    try {
      os.write(newEnvelopeJson.getBytes());
    } finally {
      os.close();
    }
  }

  private static String rewrapKey(String wrappedDataKey) throws Exception {
    String endPoint = String.format(KMS_API_REENCRYPT, KEY_TAG);

    JSONObject data = new JSONObject();
    data.put("ciphertext", wrappedDataKey);

    JSONObject respJsonObject = apiCaller(endPoint, data.toJSONString());
    String ciphertext = respJsonObject.get("newCiphertext").toString();
    return ciphertext;
  }

  private static JSONObject apiCaller(String endPoint, String data) throws Exception {
    HttpClient client = HttpClients.createDefault();

    long timestamp = System.currentTimeMillis();
    String signature = makeSignature(endPoint, timestamp);
    URIBuilder uriBuilder = new URIBuilder(KMS_API_BASE_URI);
    uriBuilder.setPath(endPoint);

    HttpPost request = new HttpPost(uriBuilder.build().toString());
    request.addHeader("x-ncp-apigw-timestamp", timestamp + "");
    request.addHeader("x-ncp-apigw-api-key", ncpApiKey); // v1を使用する場合に必要
    //request.addHeader("x-ncp-apigw-api-key", ncpApiKey); // v2を使用する場合に不要
    request.addHeader("x-ncp-iam-access-key", ncpAccessKey);
    request.addHeader("x-ncp-apigw-signature-v1", signature);
    request.addHeader("Content-Type", "application/json");
    request.setEntity(new StringEntity(data));

    HttpResponse response = client.execute(request);
    String responseBody = EntityUtils.toString(response.getEntity());
    JSONParser parser = new JSONParser();
    JSONObject repsObj = (JSONObject) parser.parse(responseBody);
    JSONObject dataObj = (JSONObject) repsObj.get("data");
    return dataObj;
  }

  private static String makeSignature(String uri , long timestamp) throws Exception {
    String message = new StringBuilder()
      .append("POST").append(" ").append(uri).append("\n")
      .append(timestamp).append("\n")
      .append(ncpApiKey).append("\n") // v1を使用する場合に必要
      //.append(ncpApiKey).append("\n") // v2を使用する場合に不要
      .append(ncpAccessKey)
      .toString();

    SecretKeySpec signingKey = new SecretKeySpec(ncpSecretKey.getBytes("UTF-8"), "HmacSHA256");
    Mac mac = Mac.getInstance("HmacSHA256");
    mac.init(signingKey);
    byte[] rawHmac = mac.doFinal(message.getBytes("UTF-8"));
    String encodeBase64String = Base64.getEncoder().encodeToString(rawHmac);
    return encodeBase64String;
  }
}

作成結果

サンプルコードの作成結果は次の通りです。

{
  "ciphertext":"wh6wryZ5MUrzlzd7EW9OYNek+3taxNVnxAcUPBRR6vtDH29tDrFxLyNukqUT3s7i",
  "iv":"HDlrArTVqwHQJRx9IhtqzQ==",
  "wrappedKey":"ncpkms:v2:lNZubJHJ4coJConKPBf4gYghFN0h\/rjHmOBtvVbTXmXynRcKhPxPNrjkCTgurBZ4a7Fb7+\/8dVKcC33R"
}

Java SDKの使用

Key Management Service APIで提供する Java SDK(Maven project)を利用して、手軽に API Gatewayを介して Key Management Service APIを呼び出すユースケースを紹介します。

参考

Key Management Service Java Client SDKのダウンロードは Key Management Service の仕様をご参照ください。

接続

すべてのリクエストは ApiClientオブジェクトを介して呼び出されます。ApiClientオブジェクトは認証情報を設定して作成します。方法は次の通りです。
認証情報の設定: Key Management Service APIは API Gatewayを介して呼び出され、API Gatewayに登録された API Key認証と Sub Account(IAM)認証を行います。

  • プロパティファイルを利用した認証
    • 認証情報を設定したプロパティファイルを利用してPropertiesFileCredentialsProviderオブジェクトを作成して認証を実行します。

      type=iam
      apiKey="API Gatewayに設定された API Key"
      accessKey="Sub Accountに設定されたサブアカウントの Access Key"
      secretKey="Sub Accountに設定されたサブアカウントの Secret Key"
      

      上記の形式で credentials.propertiesという名前の認証情報ファイルで作成します。credentials.propertiesは適切な保護とアクセス制御を通じて、流出しないようにご注意ください。Credentials.propertiesが用意されたら、あらかじめ定義した形式のビルダーで ApiClientオブジェクトを作成します。

    • Javaで作成したサンプルコードは、次の通りです。

      public void setUp() {
        apiClient = new ApiClient.ApiClientBuilder()
          .addMarshaller(JsonMarshaller.getInstance())
          .addMarshaller(XmlMarshaller.getInstance())
          .addMarshaller(FormMarshaller.getInstance())
          .setCredentials(new PropertiesFileCredentialsProvider("credentials.properties").getCredentials()) //認証情報設定
          .setLogging(true)
          .build();
      
        api = new V1Api(apiClient);
      }
      
  • Serverロールによる認証
    • NAVERクラウドプラットフォームの VPC環境の Serverで使用できる認証方式です。VPC Serverで KMS APIを使用する場合には、Server Roleで別途の認証情報を入力することなく Java SDKを使用できます。ポリシーとロール設定に関する詳細は、Sub Accountのポリシーとロール管理をご参照ください。ポリシーは NCP KMS MANAGERを、ロールを所有したリソースは KMS Java SDKを使用する VPC Serverを指定します。

      参考

      現在ユーザー定義ポリシー使用のために改善を実行しているので、ユーザー定義ポリシー設定が適用されるまで NCP KMS MANAGERを設定して使用します。

    • 設定が完了したら、ServerRoleCredentialsProviderオブジェクトを利用してあらかじめ定義した形式のビルダーで ApiClientオブジェクトを作成します。

    • Javaで作成したサンプルコードは、次の通りです。

      public void setUp() {
        apiClient = new ApiClient.ApiClientBuilder()
          .addMarshaller(JsonMarshaller.getInstance())
          .addMarshaller(XmlMarshaller.getInstance())
          .addMarshaller(FormMarshaller.getInstance())
          .setCredentialsProvider(new ServerRoleCredentialsProvider()) // Server Role認証
          .setLogging(true)
          .build();
      
        api = new V1Api(apiClient);
      }
      

API呼び出し

Key Management Serviceで作成したキーを使用して暗号化/復号化と署名/検証を行うための APIを呼び出す方法と、呼び出しのユースケースを紹介します。

  • 暗号化

    • 呼び出し方法は次の通りです。
      Encryptを参照
    • 呼び出しのユースケースは次の通りです。
      public void keyTagEncryptPostTest() throws ApiException, SdkException {
          String keyTag = "53fdfdc1d875625d9cffc317e9c729c1febc5849328eb15b7b75ba17eb17e70c";
          EncryptRequestBody body = new EncryptRequestBody();
          String plaintext = Base64.getEncoder().encodeToString("This is a test.".getBytes());
          body.setPlaintext(plaintext);
      
          try {
              api.keyTagEncryptPost(keyTag, body);
              // Handler Successful response
          } catch (ApiException e) {
              // Handler Failed response
              e.printStackTrace();
          } catch (SdkException e) {
              // Handle exceptions that occurred before communication with the server
              e.printStackTrace();
          }
      }
      
  • 復号化

    • 呼び出し方法は次の通りです。
      Decryptを参照
    • 呼び出しのユースケースは次の通りです。
      public void keyTagDecryptPostTest() throws ApiException, SdkException {
          String keyTag = "53fdfdc1d875625d9cffc317e9c729c1febc5849328eb15b7b75ba17eb17e70c";
          DecryptRequestBody body = new DecryptRequestBody();
          String ciphertext = "ncpkms:v1:eEEYwgBf/HGmqUEbTV/rASoJjneBjII+dOTnFYVOlvTnyw/+SFjwvjHpUg==";
          body.setCiphertext(ciphertext);
      
          try {
              api.keyTagDecryptPost(keyTag, body);
              // Handler Successful response
          } catch (ApiException e) {
              // Handler Failed response
              e.printStackTrace();
          } catch (SdkException e) {
              // Handle exceptions that occurred before communication with the server
              e.printStackTrace();
          }
      }
      
  • user custom key作成

    • 呼び出し方法は次の通りです。
      Create user custom keyを参照
    • 呼び出しのユースケースは次の通りです。
      public void keyTagCreateCustomKeyPostTest() throws ApiException, SdkException {
          String keyTag = "53fdfdc1d875625d9cffc317e9c729c1febc5849328eb15b7b75ba17eb17e70c";
          CreateCustomKeyRequestBody body = new CreateCustomKeyRequestBody();
          body.setRequestPlainKey(true); // Required parameter
          body.setBits(512); // Optional parameter
      
          try {
              api.keyTagCreateCustomKeyPost(keyTag, body);
              // Handler Successful response
          } catch (ApiException e) {
              // Handler Failed response
              e.printStackTrace();
          } catch (SdkException e) {
              // Handle exceptions that occurred before communication with the server
              e.printStackTrace();
          }
      }
      
  • 再暗号化

    • 呼び出し方法は次の通りです。
      Re-encryptを参照
    • 呼び出しのユースケースは次の通りです。
      public void keyTagReencryptPostTest() throws ApiException, SdkException {
          String keyTag = "53fdfdc1d875625d9cffc317e9c729c1febc5849328eb15b7b75ba17eb17e70c";
          ReencryptRequestBody body = new ReencryptRequestBody();
          String ciphertext = "ncpkms:v1:eEEYwgBf/HGmqUEbTV/rASoJjneBjII+dOTnFYVOlvTnyw/+SFjwvjHpUg==";
          body.setCiphertext(ciphertext);
      
          try {
              api.keyTagReencryptPost(keyTag, body);
              // Handler Successful response
          } catch (ApiException e) {
              // Handler Failed response
              e.printStackTrace();
          } catch (SdkException e) {
              // Handle exceptions that occurred before communication with the server
              e.printStackTrace();
          }
      }
      
  • 署名

    • 呼び出し方法は次の通りです。
      Signを参照
    • 呼び出しのユースケースは次の通りです。
      public void keyTagSignPostTest() throws ApiException, SdkException {
          String keyTag = "4f81e47fae0a28dd50b9e5e0c3a204e371afa6d35b78b81cf802b80a2aa780ab";
          SignRequestBody body = new SignRequestBody();
          String data = "Test message";
          body.setData(Base64.getEncoder().encodeToString(data.getBytes()));
      
          try {
              api.keyTagSignPost(keyTag, body);
              // Handler Successful response
          } catch (ApiException e) {
              // Handler Failed response
              e.printStackTrace();
          } catch (SdkException e) {
              // Handle exceptions that occurred before communication with the server
              e.printStackTrace();
          }
      }
      
  • 検証

    • 呼び出し方法は次の通りです。
      Verifyを参照
    • 呼び出しのユースケースは次の通りです。
      public void keyTagVerifyPostTest() throws ApiException, SdkException {
          String keyTag = "4f81e47fae0a28dd50b9e5e0c3a204e371afa6d35b78b81cf802b80a2aa780ab";
          VerifyRequestBody body = new VerifyRequestBody();
          String data = "Test message";
          body.setData(Base64.getEncoder().encodeToString(data.getBytes()));
          body.setSignature("ncpkms:v1:MEUCIQDkn9k3voN2ABewgCAortmV4HVDXSok9bS+DX+GDd1hzAIgcIndWRNmx5j9zjMoDk9NYF3M5kk+KvRyYBVXGREVx1E=");
      
          try {
              api.keyTagVerifyPost(keyTag, body);
              // Handler Successful response
          } catch (ApiException e) {
              // Handler Failed response
              e.printStackTrace();
          } catch (SdkException e) {
              // Handle exceptions that occurred before communication with the server
              e.printStackTrace();
          }
      }