[JAVA] I tried using Alibaba Cloud's KMS (Key Management Service) service

Last time tried using Alibaba Cloud's Cloud Monitor service, but this time, I will try to operate Alibaba Cloud's KMS (Key Management Service) service.

vendor Service name
AlibabaCloud Key Management Service
AWS Key Management Service
GCP Cloud Key Management Service
Azure Azure Vault

Key Management Service(KMS)

KMS (Key Management Service) is an easy-to-use service that allows you to create, control, and securely store encryption keys used to protect your data. You can use the API, SDK or console to generate a Customer Master Key (CMK) and use it to manage your encryption keys. What problems can I solve with KMS?

role problem How to use KMS to solve the problem
application/Website developer プログラムは、暗号化のためのキーを使用する必要があります。キーを安全かつ独立して管理する必要があります。applicationがどこにあってもキーに安全にアクセスする必要があります。 Embedded encryption technology allows users to store Customer Master Keys (CMKs) in KMS and deploy only encrypted data keys. In addition, the user can call the KMS API to decrypt the data key only when needed.
Service developer The developer does not want to be responsible for the security of the user's keys and data. Users need to manage their keys personally, but developers can simply use the keys they specify to focus on development. Based on envelope encryption technology and KMS's public API, service developers use the specified CMK to encrypt their data keys./It can be decrypted. Key management is left to the user.
Security officer Company key management is required to meet compliance requirements. The responsible person must ensure that the key is approved step by step and the use of the key is audited. KMS can be associated with RAM for integrated authentication management.

This time, from the standpoint of an application / website developer, I would like to use the SDK (Java) of KMS (Key Management Service) to verify the encryption and compound processing of text information with the Customer Master Key (CMK).

procedure

Well, let's work. Our goals will cover everything from creating a Customer Master Key (CMK) to implementing an encryption complex of text information using the SDK.

  1. Creating a Customer Master Key (CMK)
  2. Get Access Key
  3. Encryption and combined processing verification

1. Creating a Customer Master Key (CMK)

■ Creating a CMK

-Log on to the [KMS Console]. · Click the Create Key button in the upper right corner of the page. スクリーンショット 2018-05-12 21.24.32.png ・ Enter information such as description. -Click [OK]. スクリーンショット 2018-05-12 21.25.17.png

2. Get Access Key

■ Acquisition of Access Key

-Click the [Access Keys] button at the top of the home page. スクリーンショット 2018-05-12 21.31.46.png -Click the "Continue to manage Access Key" button on the confirmation screen for security tips. スクリーンショット 2018-05-12 21.32.26.png -When you are redirected to the Access Key management page, click the [Create Access Key] button. スクリーンショット 2018-05-12 21.37.34.png -When the key creation is completed, click the [Display] link and make a note of the displayed Access Key ID and Access Key Secret information. * It is necessary to use it for the encryption complex program described later. スクリーンショット 2018-05-12 21.37.59.png スクリーンショット 2018-05-12 21.38.16.png

3. Encryption and combined processing verification

■ Creating a verification project

-Create a Maven Project from Eclipse. * Please refer to the input information at the time of creation. Can be changed  Group Id:com.kms  Artifact Id:kms-test -Added the dependency settings of the following two Alibaba Cloud SDK libraries used for verification to the pom file.  aliyun-java-sdk-core  aliyun-java-sdk-kms

pom.xml


<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>com.kms</groupId>
  <artifactId>kms-test</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>kms-test</name>
  <url>http://maven.apache.org</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
	<dependency>
	    <groupId>com.aliyun</groupId>
	    <artifactId>aliyun-java-sdk-core</artifactId>
	    <version>3.5.0</version>
	</dependency>
	<dependency>
	    <groupId>com.aliyun</groupId>
	    <artifactId>aliyun-java-sdk-kms</artifactId>
	    <version>2.5.0</version>
	</dependency>
  </dependencies>
</project>

■ Creation of verification program

Create the following verification flow program. ・ List of all CMKs ・ Acquisition of CMK information ・ Hello world Plaintext is encrypted with CMK ・ Hello world Ciphertext is compounded with CMK

App.java


package com.kms.kms_test;

import java.util.*;
import java.util.List;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.http.FormatType;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.http.ProtocolType;
//Current KMS SDK version:2016-01-20
import com.aliyuncs.kms.model.v20160120.DecryptRequest;
import com.aliyuncs.kms.model.v20160120.DecryptResponse;
import com.aliyuncs.kms.model.v20160120.DescribeKeyRequest;
import com.aliyuncs.kms.model.v20160120.DescribeKeyResponse;
import com.aliyuncs.kms.model.v20160120.EncryptRequest;
import com.aliyuncs.kms.model.v20160120.EncryptResponse;
import com.aliyuncs.kms.model.v20160120.GenerateDataKeyRequest;
import com.aliyuncs.kms.model.v20160120.GenerateDataKeyResponse;
import com.aliyuncs.kms.model.v20160120.ListKeysRequest;
import com.aliyuncs.kms.model.v20160120.ListKeysResponse;
import com.aliyuncs.kms.model.v20160120.ListKeysResponse.Key;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
public class App
{
    static DefaultAcsClient kmsClient;
    //Aliyun client creation
    private static DefaultAcsClient kmsClient(String regionId, String accessKeyId, String accessKeySecret) {
        /**
         *Aliyun client creation:
         * RegionId, AccessKeyId,Set AccessKeySecret
         */
        IClientProfile profile = DefaultProfile.getProfile(regionId, accessKeyId, accessKeySecret);
        DefaultAcsClient client = new DefaultAcsClient(profile);
        return client;
    }
    //Get detailed information on CMK
    private static DescribeKeyResponse DescribeKey(String keyId) throws ClientException {
        final DescribeKeyRequest decKeyReq = new DescribeKeyRequest();
        decKeyReq.setProtocol(ProtocolType.HTTPS);
        decKeyReq.setAcceptFormat(FormatType.JSON);
        decKeyReq.setMethod(MethodType.POST);
        decKeyReq.setKeyId(keyId);
        final DescribeKeyResponse decKeyRes = kmsClient.getAcsResponse(decKeyReq);
        return decKeyRes;
    }
    //Get list information of registered CMK
    private static ListKeysResponse ListKey(int pageNumber, int pageSize) throws ClientException {
        final ListKeysRequest listKeysReq = new ListKeysRequest();
        listKeysReq.setProtocol(ProtocolType.HTTPS);
        listKeysReq.setAcceptFormat(FormatType.JSON);
        listKeysReq.setMethod(MethodType.POST);
        listKeysReq.setPageNumber(pageNumber);
        listKeysReq.setPageSize(pageSize);
        final ListKeysResponse listKeysRes = kmsClient.getAcsResponse(listKeysReq);
        return listKeysRes;
    }
    //Get data key information
    private static GenerateDataKeyResponse GenerateDataKey(String keyId, String keyDesc, int numOfBytes) throws ClientException {
        final  GenerateDataKeyRequest genDKReq = new GenerateDataKeyRequest();
        genDKReq.setProtocol(ProtocolType.HTTPS);
        genDKReq.setAcceptFormat(FormatType.JSON);
        genDKReq.setMethod(MethodType.POST);
        /**
         *Set the parameters according to the KMS openAPI documentation.
         * 1.KeyId
         * 2.KeyDescription
         * 3.NumberOfBytes
         */
        genDKReq.setKeySpec(keyDesc);
        genDKReq.setKeyId(keyId);
        genDKReq.setNumberOfBytes(numOfBytes);
        final GenerateDataKeyResponse genDKRes = kmsClient.getAcsResponse(genDKReq);
        return genDKRes;
    }
    //Perform encryption processing
    private static  EncryptResponse Encrypt(String keyId, String plainText) throws ClientException {
        final EncryptRequest encReq = new EncryptRequest();
        encReq.setProtocol(ProtocolType.HTTPS);
        encReq.setAcceptFormat(FormatType.JSON);
        encReq.setMethod(MethodType.POST);
        encReq.setKeyId(keyId);
        encReq.setPlaintext(plainText);
        final EncryptResponse encResponse = kmsClient.getAcsResponse(encReq);
        return encResponse;
    }
    //Perform complex processing
    private static DecryptResponse Decrypt(String cipherBlob) throws ClientException {
        final DecryptRequest decReq = new DecryptRequest();
        decReq.setProtocol(ProtocolType.HTTPS);
        decReq.setAcceptFormat(FormatType.JSON);
        decReq.setMethod(MethodType.POST);
        decReq.setCiphertextBlob(cipherBlob);
        final DecryptResponse decResponse = kmsClient.getAcsResponse(decReq);
        return decResponse;
    }
    public static void main(String[] args) {
        System.out.println("===========================================");
        System.out.println("Starting with KMS service");
        System.out.println("===========================================\n");
        /**
         *Set access information
         */
        String regionId = "ap-northeast-1";
        String accessKeyId = "★★ Set the Access Key ID you wrote down in the previous step ★★";
        String accessKeySecret = "★★ Set the Access Key Secret you noted in the previous step ★★";
        kmsClient = kmsClient(regionId, accessKeyId, accessKeySecret);
        String keyId = null;
        String plainText = "hello world";
        String cipherBlob = null;
        /*List all master keys in your account*/
        try {
            final ListKeysResponse listKeysRes = ListKey(1, 100);
            /**
             *Analyze the response and process it further
             */
            System.out.println("TotalCount: " + listKeysRes.getTotalCount());
            System.out.println("PageNumber: " + listKeysRes.getPageNumber());
            System.out.println("PageSize: " + listKeysRes.getPageSize());
            List<Key> keys = listKeysRes.getKeys();
            Iterator<Key> iterator = keys.iterator();
            while (iterator.hasNext()) {
                keyId = iterator.next().getKeyId();
                System.out.println("KeyId: " + keyId);
            }
            System.out.println("===========================================");
            System.out.println("Successful listing of all CMKs!\n");
            System.out.println("===========================================\n");
        } catch (ClientException eResponse) {
            System.out.println("Failed.");
            System.out.println("Error code: " + eResponse.getErrCode());
            System.out.println("Error message: " + eResponse.getErrMsg());
        }
        /*Key description*/
        try {
            final DescribeKeyResponse decKeyRes = DescribeKey(keyId);
            /**
             *Analyze the response and process it further
             */
            System.out.println("DescribeKey Response: ");
            DescribeKeyResponse.KeyMetadata meta = decKeyRes.getKeyMetadata();
            System.out.println("KeyId: " + meta.getKeyId());
            System.out.println("Description: " + meta.getDescription());
            System.out.println("KeyState: " + meta.getKeyState());
            System.out.println("KeyUsage: " + meta.getKeyUsage());
            System.out.println("===========================================");
            System.out.println("Successful acquisition of CMK information!");
            System.out.println("===========================================\n");
        } catch (ClientException eResponse) {
            System.out.println("Failed.");
            System.out.println("Error code: " + eResponse.getErrCode());
            System.out.println("Error message: " + eResponse.getErrMsg());
        }
        /*Data key creation*/
        /**
         *Request and get respawn
         */
        try {
            final GenerateDataKeyResponse genDKResponse = GenerateDataKey(keyId, "AES_256", 64);
            /**
             *Analyze the response and process it further
             */
            System.out.println("CiphertextBlob: " + genDKResponse.getCiphertextBlob());
            System.out.println("KeyId: " + genDKResponse.getKeyId());
            System.out.println("Plaintext: " + genDKResponse.getPlaintext());
            System.out.println("===========================================");
            System.out.println("Successful data key creation!");
            System.out.println("===========================================\n");
        } catch (ClientException eResponse) {
            System.out.println("Failed.");
            System.out.println("Error code: " + eResponse.getErrCode());
            System.out.println("Error message: " + eResponse.getErrMsg());
        }
        /**
         *Get the cipher by encrypting plain text
         */
        try {
            EncryptResponse encResponse = Encrypt(keyId, plainText);
            cipherBlob = encResponse.getCiphertextBlob();
            System.out.println("CiphertextBlob: " + cipherBlob);
            System.out.println("KeyId: " + encResponse.getKeyId());
            System.out.println("===========================================");
            System.out.println("Successful encryption of plaintext!");
            System.out.println("===========================================\n");
        } catch (ClientException eResponse) {
            System.out.println("Failed.");
            System.out.println("Error code: " + eResponse.getErrCode());
            System.out.println("Error message: " + eResponse.getErrMsg());
        }
        /**
         *Decrypt the encrypted text and verify the result in the original plaintext.
         */
        try {
            DecryptResponse decResponse = Decrypt(cipherBlob);
            System.out.println("Plaintext: " + decResponse.getPlaintext());
            String verifyPlainText = decResponse.getPlaintext();
            int isMatch = verifyPlainText.compareTo(plainText);
            System.out.println("KeyId: " + decResponse.getKeyId());
            System.out.println("===========================================");
            System.out.printf("Successful decryption of encrypted text, result" + (isMatch == 0 ? "match" + "\n" : "mismatch" + "\n"));
            System.out.println("===========================================\n");
        } catch (ClientException eResponse) {
            System.out.println("Failed.");
            System.out.println("Error code: " + eResponse.getErrCode());
            System.out.println("Error message: " + eResponse.getErrMsg());
        }
    }
}

■ Build and run a verification project

-The fold configuration of the project built with Maven is as follows. * You can also check the SDK library version of Alibaba Cloud. スクリーンショット 2018-05-12 22.30.03.png

-Run the project. The execution result is as follows.

===========================================
Starting with KMS service
===========================================

TotalCount: 3
PageNumber: 1
PageSize: 100
KeyId: 0cc16ce2-a542-4859-a778-3131a2185d79
KeyId: 4f9cb01a-f2b8-49f8-8518-4f0faf99bfa8
KeyId: bb8749d6-06a6-42bd-9724-6811a46c3bb8
===========================================
Successful listing of all CMKs!

===========================================

DescribeKey Response: 
KeyId: bb8749d6-06a6-42bd-9724-6811a46c3bb8
Description:For KMS test
KeyState: Enabled
KeyUsage: ENCRYPT/DECRYPT
===========================================
Successful acquisition of CMK information!
===========================================

CiphertextBlob: NTJiODkwZTMtOTE5My00YTlkLTkxMmYtZDU1YjRkZTMxMTYxTURGUlQvMTFtbTFId1ZOMHFhVzEySWpYVmhjWmRiR0xBQUFBQUFBQUFBQVFsREU2TXV5Ukd3R2FCUWtMSjlHRjUycDh4aTQ3YmxTWDFYR0xjOEd0SWU5cWtsRWdGWm40WGpnK2xlbzVXbXl1WkpHY04wOWJRdUh3dnNZTXFCQUxtY3NLUkdGUTJxdUYzdFF3aXhIYVBzcXMxbmkxVzBEeGFkVGZWcGtXdmZtNDBnN0JFbDNTV3c9PQ==
KeyId: bb8749d6-06a6-42bd-9724-6811a46c3bb8
Plaintext: hlSY2y9iOEWKg39MAC5p6sxm7b3KtKyHchgs2urCG9lG0bEp2p3yKugDUTASbMF6WQhj4dhZUqNeNry0R2FpGg==
===========================================
Successful data key creation!
===========================================

CiphertextBlob: NTJiODkwZTMtOTE5My00YTlkLTkxMmYtZDU1YjRkZTMxMTYxaytYdGpzRS9sK2ZQRjhCM21ad3pZZmlGOHM4NUp3MVpBQUFBQUFBQUFBQXlaa0syTzdocEI2bjJubTFwTWtHVnJLa2NyYnRMa2xCcCs1WT0=
KeyId: bb8749d6-06a6-42bd-9724-6811a46c3bb8
===========================================
Successful encryption of plaintext!
===========================================

Plaintext: hello world
KeyId: bb8749d6-06a6-42bd-9724-6811a46c3bb8
===========================================
Successful decryption of encrypted text, result match
===========================================

in conclusion

This time, I tried to verify the encryption and compound processing of text information using the SDK of KMS (Key Management Service). From now on, let's create and manage the encryption key used in the program in KMS so that it can be managed safely and independently.

Recommended Posts

I tried using Alibaba Cloud's KMS (Key Management Service) service
I tried using Gson
I tried using TestNG
I tried using Galasa
I tried using azure cloud-init
I tried using Apache Wicket
I tried using Java REPL
I tried using anakia + Jing now
I tried using Spring + Mybatis + DbUnit
I tried using JOOQ with Gradle
I tried using the cache function of Application Container Cloud Service
I tried using Java8 Stream API
I tried using JWT in Java
[Android] I tried using Coordinator Layout.
I tried using Pari gp container
I tried using WebAssembly Stadio (2018/4/17 version)
I tried using Java memo LocalDate
I tried using GoogleHttpClient of Java
I tried using Elasticsearch API in Java
I tried using Realm with Swift UI
I tried using Java's diagnostic tool Arthas
I tried using UICollectionViewListCell added from Xcode12.
I tried using Scalar DL with Docker
Envelope encryption with AWS Key Management Service
I tried using OnlineConverter with SpringBoot + JODConverter
I tried time-saving management learning with Studyplus.
It's new, but I tried using Groonga
I tried using OpenCV with Java + Tomcat
I tried using Docker for the first time
I tried using Junit on Mac VScode Maven
[For beginners] I tried using DBUnit in Eclipse
I tried barcode scanning using Rails + React + QuaggaJS
[For beginners] I tried using JUnit 5 in Eclipse
I tried to develop a man-hour management tool
[Android] I quit SQLite and tried using Realm
I made blackjack with Ruby (I tried using minitest)
[API] I tried using the zip code search API
I tried to implement a server using Netty
I tried using the profiler of IntelliJ IDEA