Back to Security & Vulnerability Analysis

aws-sdk-java-v2-kms

AWS KMSJavaEncryptionSecurityCloud SecuritySpring BootCryptographyData Protection
282📄 MIT🕒 2026-06-15Source ↗

Install this skill

npx skills add giuseppe-trisciuoglio/developer-kit

Works across Claude Code, Cursor, Codex, Copilot & Antigravity

The aws-sdk-java-v2-kms skill provides a structured framework for interacting with AWS Key Management Service using the version 2 Java SDK. It offers programmatic control over cryptographic assets by enabling developers to manage symmetric and asymmetric keys, handle key lifecycle states, and perform direct encryption or decryption operations. The skill emphasizes the implementation of envelope encryption patterns, where a master key protects a temporary data key used for local data processing, reducing latency and service calls. It bridges the gap between raw AWS API requests and Java development workflows, offering patterns for Spring Boot environments and robust client configuration options including custom retry policies and region-specific management. This tool is intended for developers maintaining security-sensitive Java applications requiring integration with AWS infrastructure for data protection and secure credential management.

When to Use This Skill

  • Protecting sensitive application logs or database fields using KMS-backed envelope encryption
  • Automating the lifecycle of encryption keys across different deployment environments
  • Integrating digital signature verification into microservices for data integrity
  • Implementing regulatory-compliant key rotation and administrative control within a Java backend

How to Invoke This Skill

Example prompts that trigger this skill in Claude Code, Cursor, or Antigravity:

  • how do I encrypt data using AWS KMS in Java 2.x
  • implementing envelope encryption with AWS SDK for Java
  • create and manage KMS keys programmatically in Java
  • using KmsAsyncClient for non-blocking encryption
  • configure AWS KMS client with custom retry policy in Java

Pro Tips

  • 💡Always follow the principle of least privilege when defining KMS key policies, ensuring only necessary entities have access to cryptographic operations.
  • 💡Utilize envelope encryption for large datasets by generating data keys from KMS and encrypting data locally, reducing KMS API costs and latency while maintaining central key management.
  • 💡Implement robust error handling and retry mechanisms for KMS API calls, especially when dealing with key availability or throttling limits.

What this skill does

  • Programmatic management of KMS key states, including enabling, disabling, and describing metadata
  • Direct execution of cryptographic operations for small to medium-sized payloads
  • Generation of unique data encryption keys for local envelope encryption
  • Support for both synchronous and asynchronous non-blocking client request patterns
  • Configuration of custom retry policies and secure credential provider chains

When not to use it

  • Performing bulk file encryption for terabyte-scale data where local hardware acceleration is superior
  • Managing high-frequency, low-latency encryption that exceeds KMS request quotas

Example workflow

  1. Initialize the KmsClient using DefaultCredentialsProvider for secure authentication
  2. Request a new data key from KMS to establish an encryption master key session
  3. Encrypt the target application data locally using the generated data key's plaintext
  4. Wipe the plaintext data key from memory immediately after the local encryption operation
  5. Store the ciphertext of the data key alongside the encrypted application data

Prerequisites

  • AWS account with active IAM credentials
  • KMS key alias or ARN already configured in the AWS console
  • Java 8 or higher development environment

Pitfalls & limitations

  • !Failure to zero-out or clear the plaintext data key from memory after use creates a potential security exposure
  • !Exceeding KMS per-second request limits can cause runtime throttling in high-throughput applications
  • !Misconfiguring AWS regions leads to connectivity failures if the key is not local to the client instance

FAQ

Should I use the synchronous or asynchronous KMS client?
Use KmsClient for standard sequential operations and KmsAsyncClient when your application requires non-blocking performance to prevent thread starvation in reactive environments.
How do I ensure I am not leaking plaintext keys?
Always manually clear the byte arrays containing plaintext data keys immediately after the local encryption or decryption process completes.
Can I use this for asymmetric encryption?
Yes, the SDK supports key usage types for signing and verification, provided the KMS key is explicitly configured for asymmetric operations.

How it compares

Compared to generic HTTP wrappers, this skill offers type-safe Request/Response objects and built-in handling of AWS authentication headers and retry logic, preventing manual serialization errors.

Source & trust

282 stars📄 MIT🕒 Updated 2026-06-15
📄 Full skill instructions — original source: giuseppe-trisciuoglio/developer-kit
# AWS SDK for Java 2.x - AWS KMS (Key Management Service)

## Overview

This skill provides comprehensive patterns for AWS Key Management Service (KMS) using AWS SDK for Java 2.x. Focus on implementing secure encryption solutions with proper key management, envelope encryption, and Spring Boot integration patterns.

## When to Use

Use this skill when:
- Creating and managing symmetric encryption keys for data protection
- Implementing client-side encryption and envelope encryption patterns
- Generating data keys for local data encryption with KMS-managed keys
- Setting up digital signatures and verification with asymmetric keys
- Integrating encryption capabilities into Spring Boot applications
- Implementing secure key lifecycle management
- Setting up key rotation policies and access controls

## Dependencies

### Maven

<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>kms</artifactId>
</dependency>


### Gradle

implementation 'software.amazon.awssdk:kms:2.x.x'


## Client Setup

### Basic Synchronous Client

import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.kms.KmsClient;

KmsClient kmsClient = KmsClient.builder()
.region(Region.US_EAST_1)
.build();


### Basic Asynchronous Client

import software.amazon.awssdk.services.kms.KmsAsyncClient;

KmsAsyncClient kmsAsyncClient = KmsAsyncClient.builder()
.region(Region.US_EAST_1)
.build();


### Advanced Client Configuration

KmsClient kmsClient = KmsClient.builder()
.region(Region.of(System.getenv("AWS_REGION")))
.credentialsProvider(DefaultCredentialsProvider.create())
.overrideConfiguration(c -> c.retryPolicy(RetryPolicy.builder()
.numRetries(3)
.build()))
.build();


## Basic Key Management

### Create Encryption Key

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


### Describe Key

public KeyMetadata getKeyMetadata(KmsClient kmsClient, String keyId) {
DescribeKeyRequest request = DescribeKeyRequest.builder()
.keyId(keyId)
.build();

return kmsClient.describeKey(request).keyMetadata();
}


### Enable/Disable Key

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


## Basic Encryption and Decryption

### Encrypt Data

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


### Decrypt Data

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


## Envelope Encryption Pattern

### Generate and Use Data Key

public DataKeyResult encryptWithEnvelope(KmsClient kmsClient, String masterKeyId, byte[] data) {
// Generate data key
GenerateDataKeyRequest keyRequest = GenerateDataKeyRequest.builder()
.keyId(masterKeyId)
.keySpec(DataKeySpec.AES_256)
.build();

GenerateDataKeyResponse keyResponse = kmsClient.generateDataKey(keyRequest);

// Encrypt data with data key
byte[] encryptedData = encryptWithAES(data,
keyResponse.plaintext().asByteArray());

// Clear plaintext key from memory
Arrays.fill(keyResponse.plaintext().asByteArray(), (byte) 0);

return new DataKeyResult(
encryptedData,
keyResponse.ciphertextBlob().asByteArray());
}

public byte[] decryptWithEnvelope(KmsClient kmsClient,
DataKeyResult encryptedEnvelope) {
// Decrypt data key
DecryptRequest keyDecryptRequest = DecryptRequest.builder()
.ciphertextBlob(SdkBytes.fromByteArray(
encryptedEnvelope.encryptedKey()))
.build();

DecryptResponse keyDecryptResponse = kmsClient.decrypt(keyDecryptRequest);

// Decrypt data with decrypted key
byte[] decryptedData = decryptWithAES(
encryptedEnvelope.encryptedData(),
keyDecryptResponse.plaintext().asByteArray());

// Clear plaintext key from memory
Arrays.fill(keyDecryptResponse.plaintext().asByteArray(), (byte) 0);

return decryptedData;
}


## Digital Signatures

### Create Signing Key and Sign Data

public String createAndSignData(KmsClient kmsClient, String description, String message) {
// Create signing key
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();

// Sign data
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());
}


### Verify Signature

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 Integration

### Configuration Class

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


### Encryption Service

@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);
}
}
}


## Examples

### Basic Encryption Example

public class BasicEncryptionExample {
public static void main(String[] args) {
KmsClient kmsClient = KmsClient.builder()
.region(Region.US_EAST_1)
.build();

// Create key
String keyId = createEncryptionKey(kmsClient, "Example encryption key");
System.out.println("Created key: " + keyId);

// Encrypt and decrypt
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);
}
}


### Envelope Encryption Example

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);

// Encrypt using envelope pattern
DataKeyResult encryptedEnvelope = encryptWithEnvelope(
kmsClient, masterKeyId, data);

// Decrypt
byte[] decryptedData = decryptWithEnvelope(
kmsClient, encryptedEnvelope);

String result = new String(decryptedData, StandardCharsets.UTF_8);
System.out.println("Decrypted: " + result);
}
}


## Best Practices

### Security
- **Always use envelope encryption for large data** - Encrypt data locally and only encrypt the data key with KMS
- **Use encryption context** - Add contextual information to track and audit usage
- **Never log sensitive data** - Avoid logging plaintext or encryption keys
- **Implement proper key lifecycle** - Enable automatic rotation and set deletion policies
- **Use separate keys for different purposes** - Don't reuse keys across multiple applications

### Performance
- **Cache encrypted data keys** - Reduce KMS API calls by caching data keys
- **Use async operations** - Leverage async clients for non-blocking I/O
- **Reuse client instances** - Don't create new clients for each operation
- **Implement connection pooling** - Configure proper connection pooling settings

### Error Handling
- **Implement retry logic** - Handle throttling exceptions with exponential backoff
- **Check key states** - Verify key is enabled before performing operations
- **Use circuit breakers** - Prevent cascading failures during KMS outages
- **Log errors comprehensively** - Include KMS error codes and context

## References

For detailed implementation patterns, advanced techniques, and comprehensive examples:

- @references/technical-guide.md - Complete technical implementation patterns
- @references/spring-boot-integration.md - Spring Boot integration patterns
- @references/testing.md - Testing strategies and examples
- @references/best-practices.md - Security and operational best practices

## Related Skills

- @aws-sdk-java-v2-core - Core AWS SDK patterns and configuration
- @aws-sdk-java-v2-dynamodb - DynamoDB integration patterns
- @aws-sdk-java-v2-secrets-manager - Secrets management patterns
- @spring-boot-dependency-injection - Spring dependency injection patterns

## External References

- [AWS KMS Developer Guide](https://docs.aws.amazon.com/kms/latest/developerguide/)
- [AWS SDK for Java 2.x Documentation](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/home.html)
- [KMS Best Practices](https://docs.aws.amazon.com/kms/latest/developerguide/best-practices.html)

How to Use This Skill Unit

Option A: Project-Specific (Recommended)

  1. Click "Download" above
  2. In your project, create the directory: .agent/skills/aws-sdk-java-v2-kms/
  3. Save the file as SKILL.md
  4. The agent will automatically discover the skill based on its description.

Option B: Global Installation (All Agents)

Save the file to these locations to make it available across all projects:

  • Claude Code: ~/.claude/skills/giuseppe-trisciuoglio/developer-kit/aws-sdk-java-v2-kms/SKILL.md
  • Cursor: ~/.cursor/skills/giuseppe-trisciuoglio/developer-kit/aws-sdk-java-v2-kms/SKILL.md
  • Antigravity: ~/.gemini/antigravity/skills/giuseppe-trisciuoglio/developer-kit/aws-sdk-java-v2-kms/SKILL.md

🚀 Install with CLI:
npx skills add giuseppe-trisciuoglio/developer-kit

Read the Master Guide: Mastering Agent Skills

Related Skill Units

Recommended Rules

View more rules

Recommended Workflows

View more workflows

Recommended MCP Servers

View more MCP servers

Take It Further

Maximize your productivity with these powerful resources

📋

Define Your Standards

Set up coding standards to ensure this workflow produces consistent, high-quality results.

Browse Rules Library
📖

Master Workflows

Learn how to create custom workflows, use Turbo Mode, and build your automation library.

Complete Guide

How to use this Skill in Claude Code & Cursor

For Claude Code (CLI)

To use this skill in Claude Code, copy the rule content into your project's custom instructions or follow our Add-Skill CLI guide. This ensures Claude follows your standards during every code generation.

For Cursor & Windsurf

For Cursor or Windsurf, individual skills are best used in the "Rules for AI" section. This specific unit helps the agent avoid security & vulnerability analysis issues, leading to cleaner, more efficient code.

Why the skill format matters: the standardized Agent Skills format lets your AI agent load detailed instructions only when they are relevant, keeping your prompt clean while improving results.

Source & attribution

This skill is categorized under Security & Vulnerability Analysis and is published by Giuseppe Trisciuoglio, maintained in giuseppe-trisciuoglio/developer-kit.

← Browse All Agent Skills
Sponsored AI assistant. Recommendations may be paid.