Aws kms encrypt/decrypt example java

What is KMS ?

KMS is a ‘Key Management System’, help you to create and manage cryptographic keys. It helps in control use of ‘cryptographic keys’ across a wide range of AWS services and in your applications.

Application can be in C#, Go, Java, Node, PHP, Python, and Ruby or you can say KMS supported languages. SDK related to all is available on AWS site.

When to Use KMS ?

KMS is to store encryption/decryption DATA keys. Further, use data keys to encrypt and decrypt, with AWS Encryption SDK.

Code Time

Gradle.xml

implementation platform('software.amazon.awssdk:bom:2.17.87')
implementation 'software.amazon.awssdk:kms'

 implementation platform('com.amazonaws:aws-java-sdk-bom:1.12.116')
 implementation 'com.amazonaws:aws-java-sdk-kms'

Java Code

@Bean
public AWSKMS kmsClient() {
   
    String apiKey = <from aws console>
    String apiSecrete = <from aws console>
    AWSCredentialsProvider credentialsProvider = null;


    AWSCredentials credentials = new BasicAWSCredentials(apiKey, apiSecrete);
    credentialsProvider = new AWSStaticCredentialsProvider(credentials);

    return AWSKMSClientBuilder.standard()
            .withCredentials(credentialsProvider)
            .withRegion(Regions.<aws region from your console>)
            .build();
}
private final AWSKMS kmsClient;

public String encrypt(String input) throws Exception {
    String kmskey = <KMS key arn from aws console>
    ByteBuffer plaintext = ByteBuffer.wrap(input.getBytes(StandardCharsets.UTF_8));
    EncryptRequest req = new EncryptRequest().withKeyId(kmskey).withPlaintext(plaintext);
    ByteBuffer ciphertext = kmsClient.encrypt(req).getCiphertextBlob();
    String data = Base64.getUrlEncoder().encodeToString(ciphertext.array());
    return data;
}
public String decrypt(String input) throws Exception {
    String kmskey = <from console>
    byte cipherBytes[] = Base64.getUrlDecoder().decode(input);
    ByteBuffer cipherBuffer = ByteBuffer.wrap(cipherBytes);
    DecryptRequest req = new DecryptRequest().withKeyId(kmskey).withCiphertextBlob(cipherBuffer);
    DecryptResult resp = kmsClient.decrypt(req);
    return new String(resp.getPlaintext().array(), Charset.forName("UTF-8"));

}

Read & Write data into AWS SQS using Java

Amazon Simple Queue Service (Amazon SQS) is a fully managed message queuing service that makes it easy to decouple and scale microservices, distributed systems, and serverless applications. Amazon SQS moves data between distributed application components and helps you decouple these components.
Before going to development install AWS SDK.
For basic theory check my page AWS SQS.
In application.yml 
sqs:
region: ap-south-1
accessKeyId: arunsinghgujjar
secretAccessKey: jainpurwalearunsingh/saharanpursepauchepuna
cloud:
aws:
end-point:
uri: https://arun-learningsubway-1.amazonaws.com/9876974864/learningsubway_SQS.fifo
queue:
max-poll-time: 20
max-messages: 10
fetch-wait-on-error: 60
enabled: true
content: sqs
In Java need to create two classes one foe send message and another to read & delete message from queue
To Send SQS Message
public static class SqsConfig {
private String region;
private String accessKeyId;
private String secretAccessKey;
}
public class SendMessageByLearningsubway {
@Value("${cloud.aws.queue.enabled}")
private Boolean enabled;
@Value("${cloud.aws.end-point.uri}")
private String url;
@Value("${cloud.aws.queue.content}")
private String queueType;
@Value("${cloud.aws.queue.max-poll-time}")
private Integer maxPollTime;
@Value("${cloud.aws.queue.max-messages}")
private Integer maxMessages;
@Value("${cloud.aws.queue.fetch-wait-on-error}")
private Integer fetchWaitOnError;
@Autowired
public SqsClient sqsClient;
public String sendMessage(MessageDistributionEvent messageDistributionEvent) {
SendMessageResponse sendMessage = null;
try {
Map<String, MessageAttributeValue> attributes = new HashMap<>();

String recepList = "";
for (Integer myInt : messageDistributionEvent.getRecipients()) {
recepList = recepList + "_" + myInt;
}
SendMessageRequest sendMsgRequest = SendMessageRequest.builder()
.queueUrl(url)
.messageBody(messageDistributionEvent.getChannelId() + "_" + messageDistributionEvent.getMessageId() + "" + recepList)
.messageGroupId("1")
.messageAttributes(attributes)
.build();
sendMessage = sqsClient.sendMessage(sendMsgRequest);
} catch (Exception ex) {
log.info("failed to send message :" + ex);
}
return sendMessage.sequenceNumber();
}
}
To Read and Delete Message
If message is not deleted, it will remain there in queue and possibility of retransmission.
public class ReceiveMessageLearningsubway {
@Value("${cloud.aws.queue.enabled}")
private Boolean enabled;
@Value("${cloud.aws.end-point.uri}")
private String url;
@Value("${cloud.aws.queue.content}")
private String queueType;
@Value("${cloud.aws.queue.max-poll-time}")
private Integer maxPollTime;
@Value("${cloud.aws.queue.max-messages}")
private Integer maxMessages;
@Value("${cloud.aws.queue.fetch-wait-on-error}")
private Integer fetchWaitOnError;
private boolean running = false;
@Autowired
public SqsClient sqsClient;
@PostConstruct
public void start() {
if (enabled && queueType.equals("sqs")) {
running = true;
new Thread(this::startListener, "sqs-listener").start();
}
}
@PreDestroy
public void stop() {
running = false;
}
private void startListener() {
while (running) {
try {
ReceiveMessageRequest receiveMessageRequest = ReceiveMessageRequest.builder()
.queueUrl(url)
.waitTimeSeconds(maxPollTime)
.maxNumberOfMessages(maxMessages)
.messageAttributeNames("MessageLabel")
.build();
List<Message> sqsMessages = sqsClient.receiveMessage(receiveMessageRequest).messages();
for (Message message : sqsMessages) {
try {
String body = message.body();
String[] data = body.split("_");
List<Integer> listRecipient = new LinkedList<>();
for (int i = 2; i < data.length; i++) {
log.info("RecepId:" + data[i]);
listRecipient.add(Integer.parseInt(data[i]));
}
//data read from queue by learningsubway.com
System.out.println(Integer.parseInt(data[0]), data[1], listRecipient);
sqsClient.deleteMessage(DeleteMessageRequest.builder()
.queueUrl(url)
.receiptHandle(message.receiptHandle())
.build());
} catch (Exception e) {
log.error("Failed to process ", message.messageId());
}
}
} catch (Exception e) {
log.warn("Error in fetching messages from SQS Queue. Will sleep and retry again.", e);
try {
Thread.sleep(fetchWaitOnError * 1000);
} catch (InterruptedException ie) {
log.error("Unable to sleep the sqs-listener", e);
}
}
}
}
public String sendMessage(QueueMessage message) {
SendMessageResponse sendMessage = null;
try {
log.info("send message on sqs");
Map<String, MessageAttributeValue> attributes = new HashMap<>();
log.info("send message on SQS: " + message);
attributes.put("ContentBasedDeduplication", MessageAttributeValue.builder().dataType("String").stringValue("true").build());
attributes.put("MessageLabel", MessageAttributeValue.builder()
.dataType("String")
.stringValue(message.getMsgId())
.build());
SendMessageRequest sendMsgRequest = SendMessageRequest.builder()
.queueUrl(url)
.messageBody(message.getMsgId())
.messageGroupId("1")
.messageAttributes(attributes)
.build();
sendMessage = sqsClient.sendMessage(sendMsgRequest);
log.info("data sent to queue: " + sendMessage.sequenceNumber());
} catch (Exception ex) {
log.info("failed to send message :" + ex);
}
return sendMessage.sequenceNumber();
}
}

AWS SQS Bucket

Amazon Simple Queue Service (SQS) is a fully managed message queuing service .

SQS eliminates the complexity and overhead associated with managing and operating message oriented middleware, and empowers developers to focus on differentiating work.

Using SQS, you can send, store, and receive messages between software components at any volume, without losing messages or requiring other services to be available. Get started with SQS in minutes using the AWS console, Command Line Interface or SDK of your choice, and three simple commands.

SQS offers two types of message queues.

  • Standard queues offer maximum throughput, best-effort ordering, and at-least-once delivery.
  • SQS FIFO queues are designed to guarantee that messages are processed exactly once, in the exact order that they are sent.

Q: How is Amazon SQS different from Amazon SNS?

Amazon SNS allows applications to send time-critical messages to multiple subscribers through a “push” mechanism, eliminating the need to periodically check or “poll” for updates.

Amazon SQS is a message queue service used by distributed applications to exchange messages through a polling model, and can be used to decouple sending and receiving components.

Q: How is Amazon SQS different from Amazon MQ?

If you’re using messaging with existing applications, and want to move your messaging to the cloud quickly and easily, recommendation is to consider Amazon MQ. It supports industry-standard APIs and protocols so you can switch from any standards-based message broker to Amazon MQ without rewriting the messaging code in your applications.

If you are building brand new applications in the cloud, we recommend you consider Amazon SQS and Amazon SNS. Amazon SQS and SNS are lightweight, fully managed message queue and topic services that scale almost infinitely and provide simple, easy-to-use APIs. 

NASA and BMW is one of the user of AWS SQS and SNS 🙂

Q: How is Amazon SQS different from Amazon Kinesis Streams?

Amazon Kinesis Streams allows real-time processing of streaming big data and the ability to read and replay records to multiple Amazon Kinesis Applications. The Amazon Kinesis Client Library (KCL) delivers all records for a given partition key to the same record processor, making it easier to build multiple applications that read from the same Amazon Kinesis stream (for example, to perform counting, aggregation, and filtering).

Q) What is the cost model of AWS SQS ?

Ans) Check it yourself