This topic provides some code samples of KMS SDK for Java.

Background information

Preparations

  1. Obtain the dependency declaration of KMS SDK for Java. For more information about the required SDK version, see SDK overview. Sample code:
    <dependency>
        <groupId>com.aliyun</groupId>
        <artifactId>aliyun-java-sdk-core</artifactId>
        <version>4.5.2</version>
    </dependency>
    <dependency>
        <groupId>com.aliyun</groupId>
        <artifactId>aliyun-java-sdk-kms</artifactId>
        <version>2.15.0</version>
    </dependency>
  2. Obtain the endpoint to access KMS based on the region where you use KMS. For more information, see Request syntax.
    Note
    • If you specify only the ID of the region, KMS SDK for Java is called by using the public endpoint for the region.
    • If you want to access KMS over a virtual private cloud (VPC), you must manually specify the internal endpoint of KMS.

Example 1: Access Secrets Manager over the Internet or a VPC

  1. Create KmsClient.
    Note If the content that you want to encrypt contains special characters <>&, we recommend that you set FormatType to XML during decryption. This helps prevent the errors caused by special character escape. For example, specify decReq.setAcceptFormat(FormatType.XML).
    package com.aliyun.kms.samples;
    
    import java.util.*;
    
    import com.aliyuncs.DefaultAcsClient;
    import com.aliyuncs.exceptions.ClientException;
    import com.aliyuncs.http.*;
    
    //Current KMS SDK version:2016-01-20
    import com.aliyuncs.kms.model.v20160120.*;
    import com.aliyuncs.kms.model.v20160120.ListKeysResponse.Key;
    import com.aliyuncs.profile.*;
    
    public class KmsClient
    {
        private DefaultAcsClient kmsClient;
    
        /**
         * Create KmsClient. You need only to specify the ID of a region. KMS SDK for Java is called by using the public endpoint for the region. 
         */
        public static KmsClient getClientForPublicEndpoint(String regionId, String accessKeyId, String accessKeySecret) {
            /**
             * Construct an Aliyun Client:
             * Set RegionId, AccessKeyId and AccessKeySecret
             */
            IClientProfile profile = DefaultProfile.getProfile(regionId, accessKeyId, accessKeySecret);
            DefaultAcsClient client = new DefaultAcsClient(profile);
            return new KmsClient(client);
        }
    
        /**
         * Create KmsClient. You can specify an internal endpoint that is accessible over a VPC. 
         */
        public static KmsClient getClientForVpcEndpoint(String regionId, String accessKeyId, String accessKeySecret, String endpoint) {
            // Specify an internal endpoint.
            DefaultProfile.addEndpoint(regionId, "kms", endpoint);
    
            IClientProfile profile = DefaultProfile.getProfile(regionId, accessKeyId, accessKeySecret);
            HttpClientConfig clientConfig = HttpClientConfig.getDefault();
            profile.setHttpClientConfig(clientConfig);
            DefaultAcsClient client = new DefaultAcsClient(profile);
            return new KmsClient(client);
        }
    
        private KmsClient(DefaultAcsClient acsClient) {
            this.kmsClient = acsClient;
        }
    
        public CreateKeyResponse CreateKey(String keyDesc, String keyUsage) throws ClientException {
            final CreateKeyRequest ckReq = new CreateKeyRequest();
    
            ckReq.setProtocol(ProtocolType.HTTPS);
            ckReq.setAcceptFormat(FormatType.JSON);
            ckReq.setMethod(MethodType.POST);
            ckReq.setDescription(keyDesc);
            ckReq.setKeyUsage(keyUsage);
    
            final CreateKeyResponse response = kmsClient.getAcsResponse(ckReq);
            return response;
        }
    
        public 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;
        }
    
        public 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;
        }
    
        public 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 parameter according to KMS openAPI document:
             * 1.KeyId
             * 2.KeyDescription
             * 3.NumberOfBytes
             */
            genDKReq.setKeySpec(keyDesc);
            genDKReq.setKeyId(keyId);
            genDKReq.setNumberOfBytes(numOfBytes);
    
            final GenerateDataKeyResponse genDKRes = kmsClient.getAcsResponse(genDKReq);
            return genDKRes;
        }
    
        public 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;
        }
    
    
        public 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;
        }
    }
  2. Use KmsClient to call KMS API operations to enumerate keys, and encrypt and decrypt data.
    Note
    • In the following sample code, your Alibaba Cloud account has at least one KMS CMK in the China (Hangzhou) region.
    • The KmsClient.getClientForPublicEndpoint method is used to initialize KmsClient to access KMS over the public endpoint.
    • The KmsClient.getClientForVpcEndpoint method is used to initialize KmsClient to access KMS over the internal endpoint.
    package com.aliyun.kms.samples;
    
    import com.aliyuncs.exceptions.ClientException;
    import com.aliyuncs.exceptions.ServerException;
    import com.google.gson.Gson;
    import java.util.*;
    import com.aliyuncs.kms.model.v20160120.*;
    import com.aliyuncs.kms.model.v20160120.ListKeysResponse.Key;
    
    public class KmsSample {
    
     public static void main(String[] args) {
            String accessKeyId = System.getenv("ACCESS_KEY_ID");
            String accessKeySecret = System.getenv("ACCESS_KEY_SECRET");
    
            KmsClient kmsClient = KmsClient.getClientForPublicEndpoint("cn-hangzhou", accessKeyId, accessKeySecret);
            //KmsClient kmsClient = KmsClient.getClientForVpcEndpoint("cn-hangzhou-vpc", accessKeyId, accessKeySecret, "kms-vpc.cn-hangzhou.aliyuncs.com");
            String keyId = null;
            String plainText = "hello world";
            String cipherBlob = null;
    
        /*List all MasterKeys in your account*/
            try {
                final ListKeysResponse listKeysRes = kmsClient.ListKey(1, 100);
    
                /**
                 * Parse response and do more 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("List All MasterKeys success!\n");
            } catch (ClientException eResponse) {
                System.out.println("Failed.");
                System.out.println("Error code: " + eResponse.getErrCode());
                System.out.println("Error message: " + eResponse.getErrMsg());
            }
    
    
            /*Describe the Key */
            try {
                final DescribeKeyResponse decKeyRes = kmsClient.DescribeKey(keyId);
    
                /**
                 * Parse response and do more 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("Describe the MasterKey success!");
                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());
            }
    
            /*Generate DataKey*/
            /**
             * Request and got response
             */
            try {
                final GenerateDataKeyResponse genDKResponse = kmsClient.GenerateDataKey(keyId, "AES_256", 64);
    
                /**
                 * Parse response and do more 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("Generate DataKey success!");
                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());
            }
    
            /**
             * Encrypt the plain text and got a cipher one
             */
            try {
                EncryptResponse encResponse = kmsClient.Encrypt(keyId, plainText);
    
                cipherBlob = encResponse.getCiphertextBlob();
                System.out.println("CiphertextBlob: " + cipherBlob);
                System.out.println("KeyId: " + encResponse.getKeyId());
    
                System.out.println("===========================================");
                System.out.println("Encrypt the plain text success!");
                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 cipher text and verify result with original plain text.
             */
            try {
                DecryptResponse decResponse = kmsClient.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("Decrypt the cipher text success, result " + (isMatch == 0 ? "match" : "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());
            }
        }
    
     }
                

Example2: Access Secrets Manager by using a client key-based application access point

If you use KMS SDK for Java to access Secrets Manager by using a client key-based application access point, you can use the following sample code:

For more information about how to create a client key, see Bind a client key to the application access point.

package com.aliyuncs.kms.sample;

import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.auth.AlibabaCloudCredentialsProvider;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
import com.aliyuncs.kms.clientkey.utils.ClientKeyUtils;

import java.io.IOException;

public class ClientKeySample {

    public static void main(String[] args) throws IOException {
        String clientKeyPath = "<client-key-file-path>";
        String password = System.getenv("<client-key-password-env-name>");
        AlibabaCloudCredentialsProvider provider = ClientKeyUtils.getCredentialsProvider(clientKeyPath, password);
        IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou");
        IAcsClient kmsClient = new DefaultAcsClient(profile, provider);
        // invoke kmsClient
    }
}

The preceding code references the following ClientKeyUtils and ClientKeyCredentialsProvider:

  • ClientKeyUtils
    package com.aliyuncs.kms.clientkey.utils;
    
    import com.aliyuncs.auth.AlibabaCloudCredentialsProvider;
    import com.aliyuncs.kms.auth.ClientKeyCredentialsProvider;
    import com.aliyuncs.auth.KeyPairCredentials;
    import com.google.gson.Gson;
    import com.google.gson.annotations.SerializedName;
    
    import java.io.*;
    import java.security.*;
    import java.security.cert.CertificateException;
    import java.util.Base64;
    import java.util.Enumeration;
    
    public class ClientKeyUtils {
    
        private final static String PKCS12 = "PKCS12";
    
        private final static Gson gson = new Gson();
    
        private ClientKeyUtils() {
            // do nothing
        }
    
        public static AlibabaCloudCredentialsProvider getCredentialsProvider(String clientKeyFileName, String password) throws IOException {
    
            try (Reader reader = new InputStreamReader(new FileInputStream(clientKeyFileName), "utf-8")) {
                ClientKeyInfo clientKeyInfo = gson.fromJson(reader, ClientKeyInfo.class);
                if (clientKeyInfo != null) {
                    byte[] pk12 = Base64.getDecoder().decode(clientKeyInfo.getPrivateKeyData());
                    try {
                        String privateKey = getPrivateKeyPemFromPk12(pk12, password);
                        return new ClientKeyCredentialsProvider(new KeyPairCredentials(clientKeyInfo.getKeyId(), privateKey));
                    } catch (Exception e) {
                        throw new IOException(e);
                    }
                } else {
                    throw new IOException("ClientKey is invalid");
                }
            }
        }
    
        private static String getPrivateKeyPemFromPk12(byte[] pk12, String password) throws KeyStoreException, CertificateException, IOException, NoSuchAlgorithmException, UnrecoverableKeyException {
            KeyStore keyStore = KeyStore.getInstance(PKCS12);
            keyStore.load(new ByteArrayInputStream(pk12), password.toCharArray());
            Enumeration<String> e = keyStore.aliases();
            String alias = e.nextElement();
            PrivateKey privateKey = (PrivateKey) keyStore.getKey(alias, password.toCharArray());
            return Base64.getEncoder().encodeToString(privateKey.getEncoded());
        }
    }
    
    class ClientKeyInfo {
        @SerializedName("KeyId")
        private String keyId;
        @SerializedName("PrivateKeyData")
        private String privateKeyData;
    
        public String getKeyId() {
            return this.keyId;
        }
    
        public void setKeyId(String keyId) {
            this.keyId = keyId;
        }
    
        public String getPrivateKeyData() {
            return this.privateKeyData;
        }
    
        public void setPrivateKeyData(String privateKeyData) {
            this.privateKeyData = privateKeyData;
        }
    }
  • ClientKeyCredentialsProvider
    package com.aliyuncs.kms.auth;
    
    import com.aliyuncs.auth.AlibabaCloudCredentials;
    import com.aliyuncs.auth.AlibabaCloudCredentialsProvider;
    import com.aliyuncs.auth.KeyPairCredentials;
    import com.aliyuncs.exceptions.ClientException;
    import com.aliyuncs.exceptions.ServerException;
    
    public class ClientKeyCredentialsProvider implements AlibabaCloudCredentialsProvider {
    
        private KeyPairCredentials keyPairCredentials;
    
        public ClientKeyCredentialsProvider() {
        }
    
        public ClientKeyCredentialsProvider(KeyPairCredentials keyPairCredentials) {
            this.keyPairCredentials = keyPairCredentials;
        }
    
        @Override
        public AlibabaCloudCredentials getCredentials() throws ClientException, ServerException {
            return this.keyPairCredentials;
        }
    }