aws-sdk-java-v2-kms
AWS SDK for Java 2.x を使用した AWS Key Management Service (KMS) のパターンを提供します。暗号化キーの作成・管理、データの暗号化・復号化、データキーの生成、デジタル署名、キーローテーション、または Spring Boot アプリケーションへの暗号化統合が必要な場合に使用してください。
description の原文を見る
Provides AWS Key Management Service (KMS) patterns using AWS SDK for Java 2.x. Use when creating/managing encryption keys, encrypting/decrypting data, generating data keys, digital signing, key rotation, or integrating encryption into Spring Boot applications.
SKILL.md 本文
AWS SDK for Java 2.x - AWS KMS (Key Management Service)
概要
AWS SDK for Java 2.x を使用した AWS KMS パターンを提供します。キー管理、暗号化・復号化、エンベロープ暗号化、デジタル署名、Spring Boot 統合をカバーしています。
使用方法
- IAM 権限の設定 - kms:* アクションに最小権限を付与
- KMS クライアントの作成 - リージョンと認証情報を使用して KmsClient をインスタンス化
- キーの作成 - createKey() を使用 → キーの状態が ENABLED であることを確認してから進める
- キーポリシーの設定 - キー使用権限を定義 → 本番環境前にアクセスをテスト
- データの暗号化 - 4KB 未満のデータは encrypt() を使用; 暗号文が空でないことを確認
- エンベロープ暗号化 - より大きなデータの場合、generateDataKey() を使用 → データキー生成が成功したことを確認
- デジタル署名 - 署名キーを作成 → 署名・検証後に signatureValid=true であることを確認
- キーローテーション - 自動ローテーションを有効化 → ローテーションスケジュールがアクティブであることを確認
使用時期
- データ保護のための対称暗号化キーの作成・管理
- 大規模データのエンベロープ暗号化の実装
- KMS 管理キーを使用したローカル暗号化のためのデータキー生成
- 非対称キーを使用したデジタル署名のセットアップ
- Spring Boot アプリケーションへの暗号化統合
依存関係
Maven
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>kms</artifactId>
</dependency>
Gradle
implementation 'software.amazon.awssdk:kms:2.x.x'
クライアントセットアップ
基本的な同期クライアント
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.kms.KmsClient;
KmsClient kmsClient = KmsClient.builder()
.region(Region.US_EAST_1)
.build();
基本的な非同期クライアント
import software.amazon.awssdk.services.kms.KmsAsyncClient;
KmsAsyncClient kmsAsyncClient = KmsAsyncClient.builder()
.region(Region.US_EAST_1)
.build();
高度なクライアント設定
KmsClient kmsClient = KmsClient.builder()
.region(Region.of(System.getenv("AWS_REGION")))
.credentialsProvider(DefaultCredentialsProvider.create())
.overrideConfiguration(c -> c.retryPolicy(RetryPolicy.builder()
.numRetries(3)
.build()))
.build();
基本的なキー管理
暗号化キーの作成
public String createEncryptionKey(KmsClient kmsClient, String description) {
CreateKeyRequest request = CreateKeyRequest.builder()
.description(description)
.keyUsage(KeyUsageType.ENCRYPT_DECRYPT)
.build();
CreateKeyResponse response = kmsClient.createKey(request);
return response.keyMetadata().keyId();
}
キーの説明情報を取得
public KeyMetadata getKeyMetadata(KmsClient kmsClient, String keyId) {
DescribeKeyRequest request = DescribeKeyRequest.builder()
.keyId(keyId)
.build();
return kmsClient.describeKey(request).keyMetadata();
}
キーの有効化・無効化
public void toggleKeyState(KmsClient kmsClient, String keyId, boolean enable) {
if (enable) {
kmsClient.enableKey(EnableKeyRequest.builder().keyId(keyId).build());
} else {
kmsClient.disableKey(DisableKeyRequest.builder().keyId(keyId).build());
}
}
基本的な暗号化と復号化
データの暗号化
public String encryptData(KmsClient kmsClient, String keyId, String plaintext) {
SdkBytes plaintextBytes = SdkBytes.fromString(plaintext, StandardCharsets.UTF_8);
EncryptRequest request = EncryptRequest.builder()
.keyId(keyId)
.plaintext(plaintextBytes)
.build();
EncryptResponse response = kmsClient.encrypt(request);
return Base64.getEncoder().encodeToString(
response.ciphertextBlob().asByteArray());
}
データの復号化
public String decryptData(KmsClient kmsClient, String ciphertextBase64) {
byte[] ciphertext = Base64.getDecoder().decode(ciphertextBase64);
SdkBytes ciphertextBytes = SdkBytes.fromByteArray(ciphertext);
DecryptRequest request = DecryptRequest.builder()
.ciphertextBlob(ciphertextBytes)
.build();
DecryptResponse response = kmsClient.decrypt(request);
return response.plaintext().asString(StandardCharsets.UTF_8);
}
エンベロープ暗号化パターン
データキーの生成と使用
public DataKeyResult encryptWithEnvelope(KmsClient kmsClient, String masterKeyId, byte[] data) {
try {
GenerateDataKeyRequest keyRequest = GenerateDataKeyRequest.builder()
.keyId(masterKeyId)
.keySpec(DataKeySpec.AES_256)
.build();
GenerateDataKeyResponse keyResponse = kmsClient.generateDataKey(keyRequest);
// レスポンスを検証
if (keyResponse.plaintext() == null || keyResponse.ciphertextBlob() == null) {
throw new IllegalStateException("Data key generation returned null");
}
byte[] encryptedData = encryptWithAES(data, keyResponse.plaintext().asByteArray());
// メモリからプレーンテキストキーをクリア
Arrays.fill(keyResponse.plaintext().asByteArray(), (byte) 0);
return new DataKeyResult(encryptedData, keyResponse.ciphertextBlob().asByteArray());
} catch (KmsException e) {
throw new RuntimeException("Envelope encryption failed: " + e.awsErrorDetails().errorCode(), e);
}
}
public byte[] decryptWithEnvelope(KmsClient kmsClient, DataKeyResult encryptedEnvelope) {
try {
DecryptRequest keyDecryptRequest = DecryptRequest.builder()
.ciphertextBlob(SdkBytes.fromByteArray(encryptedEnvelope.encryptedKey()))
.build();
DecryptResponse keyDecryptResponse = kmsClient.decrypt(keyDecryptRequest);
// レスポンスを検証
if (keyDecryptResponse.plaintext() == null) {
throw new IllegalStateException("Key decryption returned null");
}
byte[] decryptedData = decryptWithAES(
encryptedEnvelope.encryptedData(),
keyDecryptResponse.plaintext().asByteArray());
// メモリからプレーンテキストキーをクリア
Arrays.fill(keyDecryptResponse.plaintext().asByteArray(), (byte) 0);
return decryptedData;
} catch (KmsException e) {
throw new RuntimeException("Envelope decryption failed: " + e.awsErrorDetails().errorCode(), e);
}
}
デジタル署名
署名キーの作成とデータへの署名
public String createAndSignData(KmsClient kmsClient, String description, String message) {
// 署名キーを作成
CreateKeyRequest keyRequest = CreateKeyRequest.builder()
.description(description)
.keySpec(KeySpec.RSA_2048)
.keyUsage(KeyUsageType.SIGN_VERIFY)
.build();
CreateKeyResponse keyResponse = kmsClient.createKey(keyRequest);
String keyId = keyResponse.keyMetadata().keyId();
// データに署名
SignRequest signRequest = SignRequest.builder()
.keyId(keyId)
.message(SdkBytes.fromString(message, StandardCharsets.UTF_8))
.signingAlgorithm(SigningAlgorithmSpec.RSASSA_PSS_SHA_256)
.build();
SignResponse signResponse = kmsClient.sign(signRequest);
return Base64.getEncoder().encodeToString(
signResponse.signature().asByteArray());
}
署名の検証
public boolean verifySignature(KmsClient kmsClient,
String keyId,
String message,
String signatureBase64) {
byte[] signature = Base64.getDecoder().decode(signatureBase64);
VerifyRequest verifyRequest = VerifyRequest.builder()
.keyId(keyId)
.message(SdkBytes.fromString(message, StandardCharsets.UTF_8))
.signature(SdkBytes.fromByteArray(signature))
.signingAlgorithm(SigningAlgorithmSpec.RSASSA_PSS_SHA_256)
.build();
VerifyResponse verifyResponse = kmsClient.verify(verifyRequest);
return verifyResponse.signatureValid();
}
Spring Boot 統合
設定クラス
@Configuration
public class KmsConfiguration {
@Bean
public KmsClient kmsClient() {
return KmsClient.builder()
.region(Region.US_EAST_1)
.build();
}
@Bean
public KmsAsyncClient kmsAsyncClient() {
return KmsAsyncClient.builder()
.region(Region.US_EAST_1)
.build();
}
}
暗号化サービス
@Service
@RequiredArgsConstructor
public class KmsEncryptionService {
private final KmsClient kmsClient;
@Value("${kms.encryption-key-id}")
private String keyId;
public String encrypt(String plaintext) {
try {
EncryptRequest request = EncryptRequest.builder()
.keyId(keyId)
.plaintext(SdkBytes.fromString(plaintext, StandardCharsets.UTF_8))
.build();
EncryptResponse response = kmsClient.encrypt(request);
return Base64.getEncoder().encodeToString(
response.ciphertextBlob().asByteArray());
} catch (KmsException e) {
throw new RuntimeException("Encryption failed", e);
}
}
public String decrypt(String ciphertextBase64) {
try {
byte[] ciphertext = Base64.getDecoder().decode(ciphertextBase64);
DecryptRequest request = DecryptRequest.builder()
.ciphertextBlob(SdkBytes.fromByteArray(ciphertext))
.build();
DecryptResponse response = kmsClient.decrypt(request);
return response.plaintext().asString(StandardCharsets.UTF_8);
} catch (KmsException e) {
throw new RuntimeException("Decryption failed", e);
}
}
}
例
基本的な暗号化の例
public class BasicEncryptionExample {
public static void main(String[] args) {
KmsClient kmsClient = KmsClient.builder()
.region(Region.US_EAST_1)
.build();
// キーを作成
String keyId = createEncryptionKey(kmsClient, "Example encryption key");
System.out.println("Created key: " + keyId);
// 暗号化と復号化
String plaintext = "Hello, World!";
String encrypted = encryptData(kmsClient, keyId, plaintext);
String decrypted = decryptData(kmsClient, encrypted);
System.out.println("Original: " + plaintext);
System.out.println("Decrypted: " + decrypted);
}
}
エンベロープ暗号化の例
public class EnvelopeEncryptionExample {
public static void main(String[] args) {
KmsClient kmsClient = KmsClient.builder()
.region(Region.US_EAST_1)
.build();
String masterKeyId = "alias/your-master-key";
String largeData = "This is a large amount of data that needs encryption...";
byte[] data = largeData.getBytes(StandardCharsets.UTF_8);
// エンベロープパターンを使用して暗号化
DataKeyResult encryptedEnvelope = encryptWithEnvelope(
kmsClient, masterKeyId, data);
// 復号化
byte[] decryptedData = decryptWithEnvelope(
kmsClient, encryptedEnvelope);
String result = new String(decryptedData, StandardCharsets.UTF_8);
System.out.println("Decrypted: " + result);
}
}
ベストプラクティス
セキュリティ
- 大規模データには必ずエンベロープ暗号化を使用 - ローカルでデータを暗号化し、KMS でのみデータキーを暗号化
- 暗号化コンテキストを使用 - 使用追跡と監査のための文脈情報を追加
- センシティブデータをログに記録しない - プレーンテキストや暗号化キーのログを避ける
- 適切なキーライフサイクルの実装 - 自動ローテーションを有効化し、削除ポリシーを設定
- 異なる目的に異なるキーを使用 - 複数のアプリケーション間でキーを再利用しない
パフォーマンス
- 暗号化されたデータキーをキャッシュ - KMS API 呼び出しを減らすためにデータキーをキャッシュ
- 非同期操作を使用 - 非ブロッキング I/O のために非同期クライアントを活用
- クライアントインスタンスを再利用 - 操作ごとに新しいクライアントを作成しない
- 接続プーリングを実装 - 適切な接続プーリング設定を構成
エラーハンドリング
- リトライロジックを実装 - スロットリング例外を指数バックオフで処理
- キー状態を確認 - 操作前にキーが有効であることを確認
- サーキットブレーカーを使用 - KMS 停止時のカスケード障害を防止
- エラーを包括的にログ - KMS エラーコードとコンテキストを含める
参照
詳細な実装パターン、高度な技術、包括的な例については:
- @references/technical-guide.md - 完全な技術実装パターン
- @references/spring-boot-integration.md - Spring Boot 統合パターン
- @references/testing.md - テスト戦略と例
- @references/best-practices.md - セキュリティと運用のベストプラクティス
関連スキル
@aws-sdk-java-v2-core - AWS SDK コアパターンと設定@aws-sdk-java-v2-dynamodb - DynamoDB 統合パターン@aws-sdk-java-v2-secrets-manager - シークレット管理パターン@spring-boot-dependency-injection - Spring 依存性注入パターン
外部参照
制約と警告
- データサイズの制限: 直接暗号化は 4KB に制限; より大きなデータにはエンベロープ暗号化を使用
- キー使用制限: KMS は 1 秒あたりの API 呼び出しにクォータがある
- キーマテリアル: インポートされたキーマテリアルは AWS による自動ローテーション対象外
- キー削除: キー削除には 7〜30 日の待機期間が必要
- 地域的境界: KMS キーは複数のリージョン間で使用できない
- コスト考慮: KMS は API 呼び出しとキーストレージに対して課金
- 非対称キー: すべてのリージョンが非対称キータイプをサポートしていない
- キーポリシー: キーポリシーの変更には慎重な IAM レビューが必要
- エンベロープ暗号化: データキーセキュリティに適切な実装が必要
- ログ: CloudTrail を有効化して KMS API 使用をすべて監査
ライセンス: MIT(寛容ライセンスのため全文を引用しています) · 原本リポジトリ
詳細情報
- 作者
- giuseppe-trisciuoglio
- ライセンス
- MIT
- 最終更新
- 不明
Source: https://github.com/giuseppe-trisciuoglio/developer-kit / ライセンス: MIT
関連スキル
hugging-face-trackio
Trackioを使用してMLトレーニング実験を追跡・可視化できます。トレーニング中のメトリクスログ記録(Python API)、トレーニング診断のアラート発火、ログされたメトリクスの取得・分析(CLI)が必要な場合に活用してください。リアルタイムダッシュボード表示、Webhookを使用したアラート、HF Space同期、自動化向けのJSON出力に対応しています。
btc-bottom-model
ビットコインのサイクルタイミングモデルで、加重スコアリングシステムを搭載しています。日次パルス(4指標、32ポイント)とウィークリー構造(9指標、68ポイント)の2カテゴリーにわたる13の指標を追跡し、0~100のマーケットヒートスコアを算出します。ETFフロー、ファンディングレート、ロング/ショート比率、恐怖・貪欲指数、LTH-MVRV、NUPL、SOPR(LTH+STH)、LTH供給率、移動平均倍率(365日MA、200週MA)、週次RSI、出来高トレンドに対応します。市場サイクル全体を通じて買いと売りの両方の推奨を提供します。ビットコインの底値拾い、BTCサイクルポジション、買い時・売り時、オンチェーン指標、MVRV、NUPL、SOPR、LTH動向、ETFの流出入、ファンディングレート、恐怖指数、ビットコインが過熱状態か、マイナーコスト、暗号資産市場のセンチメント、BTCのポジションサイジング、「今ビットコインを買うべきか」「BTCが天井をつけているか」「オンチェーン指標は何を示しているか」といった質問の際にこのスキルを活用します。
protein_solubility_optimization
タンパク質の溶解性最適化 - タンパク質の溶解性を最適化します。タンパク質の特性を計算し、溶解性と親水性を予測し、有効な変異を提案します。タンパク質配列の特性計算、タンパク質機能の予測、親水性計算、ゼロショット配列予測を含むタンパク質エンジニアリング業務に使用できます。3つのSCPサーバーから4つのツールを統合しています。
research-lookup
Parallel Chat APIまたはPerplexity sonar-pro-searchを使用して、最新の研究情報を検索できます。学術論文の検索にも対応しています。クエリは自動的に最適なバックエンドにルーティングされるため、論文の検索、研究データの収集、科学情報の検証に活用できます。
tree-formatting
ggtree(R)またはiTOL(ウェブ)を使用して、系統樹の可視化とフォーマットを行います。系統樹を図として描画する際、ツリーレイアウトの選択、分類学に基づく枝やラベルの色付け、クレードの折りたたみ、サポート値の表示、またはツリーへのオーバーレイ追加が必要な場合に使用してください。系統推定(protein-phylogenyスキルを使用)やドメイン注釈(今後の独立したスキル)には使用しないでください。
querying-indonesian-gov-data
インドネシア政府の50以上のAPIとデータソースに接続できます。BPJPH(ハラール認証)、BOM(食品安全)、OJK(金融適正性)、BPS(統計)、BMKG(気象・地震)、インドネシア中央銀行(為替レート)、IDX(株式)、CKAN公開データポータル、pasal.id(第三者法MCP)に対応しています。インドネシア政府データを活用したアプリ開発、.go.idウェブサイトのスクレイピング、ハラール認証の確認、企業の法的適正性の検証、金融機関ステータスの照会、またはインドネシアMCPサーバーへの接続時に使用できます。CSRF処理、CKAN API使用方法、IP制限回避など、すぐに実行可能なPythonパターンを含んでいます。