# AWS KMSでの暗号化

<figure><img src="https://859776093-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FPL6k1aGsLiFiiJ3Y7zCl%2Fuploads%2Fag8WrHeCcYchXMrvhM8A%2Fimage.png?alt=media&#x26;token=d4d4b1d7-7ddc-4963-a811-aa9e98196fba" alt=""><figcaption></figcaption></figure>

KeeperシークレットマネージャーをAWS KMSと組み合わせると、構成ファイルを暗号化できます。マシン上の接続情報を保護しつつ、ボルト内のシークレットについてもKeeperのゼロ知識暗号化を利用できます。

## 機能

* AWS KMSを使い、Keeperシークレットマネージャーの構成ファイルを暗号化・復号化する
* シークレットマネージャー接続情報への不正アクセスを防ぐ
* わずかなコード変更で保護を有効化でき、すべてのKeeperシークレットマネージャーSDKの機能をそのまま利用できる

## 要件

{% tabs %}
{% tab title="Java" %}

* [Java版シークレットマネージャーSDK](/keeperpam/jp/secrets-manager/developer-sdk-library/java-sdk.md)に対応
* [AWS-KMS](https://mvnrepository.com/artifact/software.amazon.awssdk/kms)および[AWS-Auth](https://mvnrepository.com/artifact/software.amazon.awssdk/auth)パッケージが必要
* Java 11以降で利用可能
  {% endtab %}

{% tab title="JavaScript" %}

* [JavaScript版シークレットマネージャーSDK](/keeperpam/jp/secrets-manager/developer-sdk-library/javascript-sdk.md)に対応
* [aws-sdk/client-kms](https://www.npmjs.com/package/@aws-sdk/client-kms)パッケージが必要
  {% endtab %}

{% tab title="Python" %}

* [Python版シークレットマネージャーSDK](/keeperpam/jp/secrets-manager/developer-sdk-library/python-sdk.md)に対応
* boto3パッケージが必要
  {% endtab %}

{% tab title=".Net" %}

* [.NET版シークレットマネージャーSDK](/keeperpam/jp/secrets-manager/developer-sdk-library/.net-sdk.md)に対応
* [AWSSDK.KeyManagementService](https://www.nuget.org/packages/AWSSDK.KeyManagementService)パッケージが必要
  {% endtab %}
  {% endtabs %}

## セットアップ

### 1. モジュールのインストール

{% tabs %}
{% tab title="Java" %}
GradleまたはMavenでプロジェクトをセットアップします。

**Gradle**

```
repositories {
  mavenCentral()
}

dependencies {
  implementation("com.keepersecurity.secrets-manager:aws:1.0.0")
  implementation("com.keepersecurity.secrets-manager:core:17.0.0")
  implementation ("software.amazon.awssdk:kms:2.20.28")
  implementation ("software.amazon.awssdk:auth:2.20.28")
  implementation("com.fasterxml.jackson.core:jackson-databind:2.18.2")
  implementation("com.fasterxml.jackson.core:jackson-core:2.18.2")
  implementation("com.google.code.gson:gson:2.12.1")
  implementation("org.slf4j:slf4j-api:1.7.32"){
      exclude("org.slf4j:slf4j-log4j12")
  }
  implementation("ch.qos.logback:logback-classic:1.2.6")
  implementation("ch.qos.logback:logback-core:1.2.6")
  implementation("org.bouncycastle:bc-fips:1.0.2.4")
}
```

**Maven**

```xml
<!-- KMS-core -->
<dependency>
 <groupId>com.keepersecurity.secrets-manager</groupId>
 <artifactId>aws</artifactId>
 <version>1.0.0</version>
</dependency>
<dependency>
 <groupId>com.keepersecurity.secrets-manager</groupId>
 <artifactId>core</artifactId>
 <version>17.0.0</version>
</dependency>

<!-- aws-kms -->
   	<dependency>
   		<groupId>software.amazon.awssdk</groupId>
   		<artifactId>kms</artifactId>
   		<version>2.20.28</version>
   	</dependency>
   		
   	<!-- aws-auth -->
   	<dependency>
   		<groupId>software.amazon.awssdk</groupId>
   		<artifactId>auth</artifactId>
   		<version>2.20.28</version>
   	</dependency>
   	
   	<!--gson -->
   	<dependency>
   	    <groupId>com.google.code.gson</groupId>
   	    <artifactId>gson</artifactId>
   	    <version>2.12.1</version>
   	</dependency>

   	<!--jackson-core -->
   	<dependency>
   		<groupId>com.fasterxml.jackson.core</groupId>
   		<artifactId>jackson-core</artifactId>
   		<version>2.18.2</version>
   	</dependency>
   	
   	<!--jackson-databind -->
   	<dependency>
   		<groupId>com.fasterxml.jackson.core</groupId>
   		<artifactId>jackson-core</artifactId>
   		<version>2.18.2</version>
   	</dependency>
   	
   	<!-- slf4j-api -->
   	<dependency>
   		<groupId>org.slf4j</groupId>
   		<artifactId>slf4j-api</artifactId>
   		<version>1.7.32</version>
   		<scope>runtime</scope>
   	</dependency>

   	<!-- logback-classic -->
   	<dependency>
   		<groupId>ch.qos.logback</groupId>
   		<artifactId>logback-classic</artifactId>
   		<version>1.2.6</version>
   		<scope>compile</scope>
   	</dependency>

   	<!-- logback-core -->
   	<dependency>
   		<groupId>ch.qos.logback</groupId>
   		<artifactId>logback-core</artifactId>
   		<version>1.2.6</version>
   		<scope>compile</scope>
   	</dependency>
   	
   	<!-- bc-fips -->
   	<dependency>
   		<groupId>org.bouncycastle</groupId>
   		<artifactId>bc-fips</artifactId>
   		<version>1.0.2.4</version>
   	</dependency>   	
```

{% endtab %}

{% tab title="JavaScript" %}
npmで、シークレットマネージャーとAWS KMSの統合パッケージをインストールします。

```bash
npm install @keeper-security/secrets-manager-aws
```

{% endtab %}

{% tab title="Python" %}
HSM用モジュールは、Keeperシークレットマネージャーのストレージパッケージに含まれます。以下のコマンドでインストールします。

```bash
pip3 install keeper-secrets-manager-storage
```

AWS KMS連携では、あらかじめ `boto3` が必要です。以下のコマンドでインストールします。

```bash
pip install boto3
```

{% endtab %}

{% tab title=".Net" %}
以下のコマンドでシークレットマネージャーとAWS KMSの統合をインストールします。

```bash
dotnet add package Keeper.SecretsManager.AWSKeyManagement
```

{% endtab %}
{% endtabs %}

### 2. AWS接続を構成

デフォルトでは、boto3は、`aws configure` で設定したAWS CLIの既定セッションを使います。接続内容を独自に指定する場合は、`~/.aws/config` と `~/.aws/credentials` の2ファイルを手動で編集します。

{% hint style="info" %}
`aws configure` やセッションの扱いの詳細については、以下のAWS CLIリファレンスにまとまっています。<https://docs.aws.amazon.com/cli/latest/reference/configure/>
{% endhint %}

あるいは、`AwsSessionConfig` データクラスを使い、`aws_access_key_id`、`aws_secret_access_key`、`aws_session_token` にアクセスキー情報を渡して明示的に指定します。

{% hint style="info" %}
AWS KMS連携には、AWSアクセスキーが必要です。

AWSアクセスキーについて詳しくは、以下のドキュメントをご参照ください。<https://aws.amazon.com/premiumsupport/knowledge-center/create-access-key/>
{% endhint %}

### 3. AWS KMSストレージをコードに追加

AWS接続の構成が完了すると、連携を通じてKSM構成ファイルの暗号化と復号に使うキーを取得できます。シークレットマネージャーSDKでは、KMSをストレージとして使うよう指定する必要があります。

**指定された接続認証情報の使用**

{% tabs %}
{% tab title="Java" %}
この操作を行うには、`SecretsManager` コンストラクタで、`AwsKeyValueStorage` をシークレットマネージャーのストレージとして使用します。

このストレージには、AWSキーID、`AwsSessionConfig`、AWS KMSによって暗号化されるシークレットマネージャー構成ファイルの名前が必要です。

```java
import org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider;
import com.keepersecurity.secretmanager.aws.kms.AwsKeyValueStorage;
import com.keepersecurity.secretmanager.aws.kms.AwsSessionConfig;
import com.keepersecurity.secretsManager.core.InMemoryStorage;
import com.keepersecurity.secretsManager.core.SecretsManager;
import com.keepersecurity.secretsManager.core.SecretsManagerOptions;
import static com.keepersecurity.secretsManager.core.SecretsManager.initializeStorage;

import software.amazon.awssdk.regions.Region;

import java.security.Security;
import org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider;

class Test {
	public static void main(String args[]){
		String keyId = "<Key ID>";
		String awsAccessKeyId = "<AWS Access ID>";
		String awsSecretAccessKey = "<AWS Secret>";
		String oneTimeToken = "[One Time Token]";
		Region region = Region.<cloud-region>;
		String profile = null OR "DEFAULT";     //set profile (ex. DEFUALT/UAT/PROD) if ~/.aws/config is set
		String configFileLocation = "client_config_test.json";
		try{
			//set AWS configuration, It can be null if profile is set for aws credentials
			AwsSessionConfig sessionConfig = new AwsSessionConfig(awsAccessKeyId, awsSecretAccessKey);
			//Get Storage 
			AwsKeyValueStorage awskvstorage =  new AwsKeyValueStorage(keyId, configFileLocation, profile, null, region);
			initializeStorage(awskvstorage, oneTimeToken);
			SecretsManagerOptions options = new SecretsManagerOptions(awskvstorage);
			//getSecrets(OPTIONS);
		}catch (Exception e) {
			System.out.println(e.getMessage());
		}
	}
}

```

{% endtab %}

{% tab title="JavaScript" %}
この操作を行うには、`SecretsManager` コンストラクタで、`AWSKeyValueStorage` をシークレットマネージャーのストレージとして使用します。

このストレージには、AWSキーID、AWSセッション認証情報の `AWSSessionConfig`、AWS KMSによって暗号化されるシークレットマネージャー構成ファイルの名前が必要です。

```javascript
import { AWSKeyValueStorage, AWSSessionConfig, LoggerLogLevelOptions } from "@keeper-security/secrets-manager-aws";
import { initializeStorage, getSecrets } from "@keeper-security/secrets-manager-core";


const getKeeperRecordsAWS = async () => {

	const accessKeyId = "<YOUR AWS ACCESS KEY>>";
	const secretAccessKey = "<YOUR AWS SECRET_ACCESS_KEY>";
	const regionName = "<YOUR AWS REGION>";
	const logLevel = LoggerLogLevelOptions.Debug;
	const configPath = "client-config-path.json";
	
	const awsSessionConfig = new AWSSessionConfig(accessKeyId, secretAccessKey, regionName);
	const keyId = 'arn:aws:kms:ap-south-1:<accountName>:key/<keyId>';
	const storage = await new AWSKeyValueStorage(keyId, configPath, awsSessionConfig, logLevel).init();
	
	const oneTimeToken = "<one time token>";

	await initializeStorage(storage, oneTimeToken);
	const { records } = await getSecrets({ storage: storage });

	const firstRecord = records[0]
	const firstRecordPassword = firstRecord.data.fields.find(x => x.type === 'password')
	console.log(firstRecordPassword.value[0])
};
getKeeperRecordsAWS();

```

{% endtab %}

{% tab title="Python" %}
この操作を行うには、`SecretsManager` のコンストラクタで、`AwsKmsKeyValueStorage` をシークレットマネージャーのストレージとして使用します。

このストレージには、AWSキーID、`AwsSessionConfig`、AWS KMSによって暗号化されるシークレットマネージャー構成ファイルの名前が必要です。

```python
from keeper_secrets_manager_core import SecretsManager
from keeper_secrets_manager_hsm.storage_aws_kms import AwsKmsKeyValueStorage
 
aws_session_cfg = AwsSessionConfig(
    aws_access_key_id="AK[...]FIF",
    aws_secret_access_key="/[...]/g3",
    region_name="us-east-2")

config = AwsKmsKeyValueStorage(
   key_id='e9[...]567',
   config_file_location='client-config.json',
   aws_session_config=aws_session_cfg)
 
secrets_manager = SecretsManager(config=config, verify_ssl_certs=True)
all_records = secrets_manager.get_secrets()
```

{% endtab %}

{% tab title=".Net" %}
この操作を行うには、`SecretsManager` のコンストラクタで、`AwsKeyValueStorage` をシークレットマネージャーのストレージとして使用します。

このストレージには、AWSキーID、`AwsSessionConfig`、AWS KMSによって暗号化されるシークレットマネージャー構成ファイルの名前が必要です。

```csharp
using System;
using System.Linq;
using System.Threading.Tasks;
using SecretsManager;
using AWSKeyManagement;

public class Program
{
	private static async Task getOneIndividualSecret()
	{
		var accessKeyId = "<ACCESS_KEY_ID>";
		var secretAccessKey = "<SECRET_ACCESS_KEY>";
		var regionName = "<AWS_REGION_STRING";

		var keyId = "<KEY_ID_1>";
		var path = "<KEEPER_CONFIG_FILE_PATH>";
		var dotnet_access_token = "<ONE_TIME_TOKEN>";

		var awsSessionConfig = new AWSSessionConfig(accessKeyId, secretAccessKey, regionName);

		var aws_storage = new AWSKeyValueStorage(keyId, path, awsSessionConfig);

		SecretsManagerClient.InitializeStorage(aws_storage, dotnet_access_token);

		var options = new SecretsManagerOptions(aws_storage);
		var records_1 = await SecretsManagerClient.GetSecrets(options);
		records_1.Records.ToList().ForEach(record => Console.WriteLine(record.RecordUid + " - " + record.Data.title));
	}

	static async Task Main()
	{
		await getOneIndividualSecret();
	}
}
```

{% endtab %}
{% endtabs %}

**デフォルトの接続を使用**

{% tabs %}
{% tab title="Java" %}
この操作を行うには、`SecretsManager` コンストラクタで、`AwsKeyValueStorage` をシークレットマネージャーのストレージとして使用します。

このストレージには、AWSキーID、`AwsSessionConfig`、AWS KMSによって暗号化されるシークレットマネージャー構成ファイルの名前が必要です。

```java
import org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider;
import com.keepersecurity.secretmanager.aws.kms.AwsKeyValueStorage;
import com.keepersecurity.secretmanager.aws.kms.AwsSessionConfig;
import com.keepersecurity.secretsManager.core.InMemoryStorage;
import com.keepersecurity.secretsManager.core.SecretsManager;
import com.keepersecurity.secretsManager.core.SecretsManagerOptions;
import static com.keepersecurity.secretsManager.core.SecretsManager.initializeStorage;

import software.amazon.awssdk.regions.Region;

import java.security.Security;
import org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider;

class Test {
	public static void main(String args[]){
		String keyId = "<Key ID>";
		String awsAccessKeyId = "<AWS Access ID>";
		String awsSecretAccessKey = "<AWS Secret>";
		String oneTimeToken = "[One Time Token]";
		Region region = Region.<cloud-region>;
		String profile = null OR "DEFAULT";     //set profile (ex. DEFUALT/UAT/PROD) if ~/.aws/config is set
		String configFileLocation = "client_config_test.json";
		try{
			//set AWS configuration, It can be null if profile is set for aws credentials
			AwsSessionConfig sessionConfig = new AwsSessionConfig(awsAccessKeyId, awsSecretAccessKey);
			//Get Storage 
			AwsKeyValueStorage awskvstorage =  new AwsKeyValueStorage(keyId, configFileLocation, profile, sessionConfig, region);
			initializeStorage(awskvstorage, oneTimeToken);
			SecretsManagerOptions options = new SecretsManagerOptions(awskvstorage);
			//getSecrets(OPTIONS);
		}catch (Exception e) {
			System.out.println(e.getMessage());
		}
	}
}

```

{% endtab %}

{% tab title="JavaScript" %}
この操作を行うには、`SecretsManager` コンストラクタで、`AWSKeyValueStorage` をシークレットマネージャーのストレージとして使用します。

このストレージには、AWSキーID、AWSセッション認証情報の `AWSSessionConfig`、AWS KMSによって暗号化されるシークレットマネージャー構成ファイルの名前が必要です。

```javascript
import { AWSKeyValueStorage } from "@keeper-security/secrets-manager-aws";
import { initializeStorage, getSecrets } from "@keeper-security/secrets-manager-core";


const getKeeperRecordsAWS = async () => {

	const configPath = "client-config-path.json";
	
	const keyId = 'arn:aws:kms:ap-south-1:<accountName>:key/<keyId>';
	const storage = await new AWSKeyValueStorage(keyId, configPath).init();
	
	const oneTimeToken = "<one time token>";

	await initializeStorage(storage, oneTimeToken);
	const { records } = await getSecrets({ storage: storage });

	const firstRecord = records[0]
	const firstRecordPassword = firstRecord.data.fields.find(x => x.type === 'password')
	console.log(firstRecordPassword.value[0])
};
getKeeperRecordsAWS();

```

{% endtab %}

{% tab title="Python" %}
この操作を行うには、`SecretsManager` のコンストラクタで、`AwsKmsKeyValueStorage` をシークレットマネージャーのストレージとして使用します。

このストレージには、AWSキーID、AWS KMSによって暗号化されるシークレットマネージャー構成ファイルの名前が必要です。

```python
from keeper_secrets_manager_core import SecretsManager
from keeper_secrets_manager_hsm.storage_aws_kms import AwsKmsKeyValueStorage

key_id = 'c5[...]576'
    
config = AwsKmsKeyValueStorage(key_id, 'client-config.json') # default session
 
secrets_manager = SecretsManager(config=config, verify_ssl_certs=True)
all_records = secrets_manager.get_secrets()

```

{% endtab %}

{% tab title=".Net" %}
この操作を行うには、`SecretsManager` のコンストラクタで、`AWSKeyValueStorage` をシークレットマネージャーのストレージとして使用します。

このストレージには、AWSキーID、AWS KMSによって暗号化されるシークレットマネージャー構成ファイルの名前が必要です。

```csharp
using System;
using System.Linq;
using System.Threading.Tasks;
using SecretsManager;
using AWSKeyManagement;

public class Program
{
	private static async Task getOneIndividualSecret()
	{
		var keyId = "<KEY_ID_1>";
		var path = "<KEEPER_CONFIG_FILE_PATH>";
		var dotnet_access_token = "<ONE_TIME_TOKEN>";

		var aws_storage = new AWSKeyValueStorage(keyId, path);

		SecretsManagerClient.InitializeStorage(aws_storage, dotnet_access_token);

		var options = new SecretsManagerOptions(aws_storage);
		var records_1 = await SecretsManagerClient.GetSecrets(options);
		records_1.Records.ToList().ForEach(record => Console.WriteLine(record.RecordUid + " - " + record.Data.title));
	}

	static async Task Main()
	{
		await getOneIndividualSecret();
	}
}
```

{% endtab %}
{% endtabs %}

## AWS KMS連携の使用

セットアップが完了すると、シークレットマネージャーとAWS KMSの連携により、シークレットマネージャーSDKの機能をすべて利用できます。実行時に構成ファイルを復号するには、コードからAWS KMSのAPIにアクセスできる必要があります。

## 追加オプション

### キーの変更

構成の暗号化に使うキーは変更できます。以下にコード例を示します。

{% tabs %}
{% tab title="Java" %}

```java
String newkeyId = "<New-Key-ID>";
AwsKeyValueStorage awskvstorage =  new AwsKeyValueStorage(keyId, configFileLocation, profile, sessionConfig, region);
awskvstorage.changeKey(newkeyId)
```

{% endtab %}

{% tab title="JavaScript" %}

```javascript
const storage = await new AWSKeyValueStorage(keyId,config_path).init()
await initializeStorage(storage, oneTimeToken);

// do all process needed if any or change directly
await storage.changeKey(keyId2);
```

{% endtab %}

{% tab title="Python" %}

```python
from keeper_secrets_manager_core import SecretsManager
from keeper_secrets_manager_hsm.storage_aws_kms import AwsKmsKeyValueStorage
 
aws_session_cfg = AwsSessionConfig(
    aws_access_key_id="AK[...]FIF",
    aws_secret_access_key="/[...]/g3",
    region_name="<region>")

new_key_id = "<new_key_id>"
config = AwsKmsKeyValueStorage(
   key_id='e9[...]567',
   config_file_location='client-config.json',
   aws_session_config=aws_session_cfg)
 
secrets_manager = SecretsManager(config=config, verify_ssl_certs=True)
all_records = secrets_manager.change_key(new_key_id)
```

{% endtab %}

{% tab title=".Net" %}

```csharp
    using Microsoft.Extensions.Logging;

    var awsSessionConfig2 = new AWSSessionConfig();
    var loggerFactory = LoggerFactory.Create(builder =>
        {
            builder.SetMinimumLevel(LogLevel.Debug);
            builder.AddConsole();
        });

    var logger = loggerFactory.CreateLogger<AWSKeyValueStorage>();

    var aws_storage = new AWSKeyValueStorage(keyId, path, awsSessionConfig2,logger);
```

{% endtab %}
{% endtabs %}

### 構成の復号化

実装を別のクラウド環境へ移す場合や、平文の認証情報が必要な場合は、構成ファイルを復号できます。この関数はブール値を取り、`true` では復号結果をファイルに書き出し、`false` では復号した構成の内容だけを返します。

{% tabs %}
{% tab title="Java" %}

```java
AwsKeyValueStorage awskvstorage =  new AwsKeyValueStorage(keyId, configFileLocation, profile, sessionConfig, region);
awskvstorage.decryptConfig(true) // Set true as a parameter to extract plaintext and save config as a plaintext.
//OR 
awskvstorage.decryptConfig(false); // Set false as a parameter to extract only plaintext.
```

{% endtab %}

{% tab title="JavaScript" %}

```javascript
const storage = await new AWSKeyValueStorage(keyId,config_path).init();
await storage.decryptConfig(); 
```

{% endtab %}

{% tab title="Python" %}

```python
from keeper_secrets_manager_core import SecretsManager
from keeper_secrets_manager_hsm.storage_aws_kms import AwsKmsKeyValueStorage
 
aws_session_cfg = AwsSessionConfig(
    aws_access_key_id="AK[...]FIF",
    aws_secret_access_key="/[...]/g3",
    region_name="<region>")

config = AwsKmsKeyValueStorage(
   key_id='e9[...]567',
   config_file_location='client-config.json',
   aws_session_config=aws_session_cfg)
 
secrets_manager = SecretsManager(config=config, verify_ssl_certs=True)
all_records = secrets_manager.decrypt_config(True)
```

{% endtab %}

{% tab title=".Net" %}

```csharp
var conf = await aws_storage.DecryptConfigAsync(false);
Console.WriteLine(conf);   
```

{% endtab %}
{% endtabs %}

{% hint style="success" %}
KSM連携を利用する準備が整いました。
{% endhint %}

{% hint style="info" %}
その他の例と機能については、[KSM SDKのドキュメント](/keeperpam/jp/secrets-manager/developer-sdk-library.md)をご参照ください。
{% endhint %}


---

# Agent Instructions: 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.keeper.io/keeperpam/jp/secrets-manager/integrations/aws-kms.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.
