全部产品
Search
文档中心

Key Management Service:Contoh Penggunaan KMS SDK untuk Java

更新时间:Jul 02, 2025

Topik ini memberikan contoh penggunaan Key Management Service (KMS) SDK untuk Java.

Informasi Latar Belakang

  • Anda dapat mengunjungi repositori kode sumber terbuka untuk melihat contoh kode KMS SDK dalam berbagai bahasa pemrograman dan skenario. Anda dipersilakan untuk memberikan komentar atau menyediakan kode contoh Anda sendiri.

  • Untuk informasi lebih lanjut tentang operasi API KMS, lihat Daftar Operasi Berdasarkan Fungsi.

Persiapan

  1. Dapatkan deklarasi dependensi KMS SDK untuk Java. Untuk informasi lebih lanjut tentang versi SDK yang diperlukan, lihat Ikhtisar SDK. Contoh:

    <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. Dapatkan titik akhir KMS berdasarkan wilayah KMS. Untuk informasi lebih lanjut, lihat Membuat Permintaan API.

    Catatan
    • Jika Anda hanya menentukan ID wilayah KMS, titik akhir publik KMS untuk wilayah tersebut akan digunakan secara otomatis.

    • Jika Anda ingin mengakses KMS melalui virtual private cloud (VPC), Anda harus menentukan alamat VPC KMS.

Contoh 1: Mengakses KMS melalui titik akhir publik atau alamat VPC

Catatan

Pasangan AccessKey dari akun Alibaba Cloud memiliki izin untuk semua operasi API. Menggunakan pasangan AccessKey untuk melakukan operasi adalah operasi berisiko tinggi. Selain itu, gunakan pengguna RAM untuk memanggil operasi API atau melakukan pemeliharaan rutin. Kami menyarankan agar Anda tidak menyimpan ID AccessKey dan Rahasia AccessKey di kode proyek Anda. Jika Anda melakukannya, pasangan AccessKey mungkin bocor dan keamanan semua sumber daya yang dimiliki oleh akun Anda mungkin terganggu.

Dalam contoh ini, pasangan AccessKey disimpan dalam variabel lingkungan ALIBABA_CLOUD_ACCESS_KEY_ID dan ALIBABA_CLOUD_ACCESS_KEY_SECRET untuk mengimplementasikan autentikasi identitas.

  1. Panggil kelas terenkapsulasi untuk membuat klien KMS.

    Catatan

    Jika data yang ingin Anda enkripsi berisi karakter khusus <>&, kami sarankan Anda mengatur FormatType ke XML untuk mendekripsi data. Ini membantu mencegah kesalahan yang terjadi ketika karakter khusus diloloskan selama dekripsi. Sebagai contoh, tentukan 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.*;
    
    //Versi KMS SDK saat ini: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;
    
        /**
         * Buat klien KMS. Anda hanya perlu menentukan ID wilayah KMS. KMS SDK untuk Java secara otomatis mendapatkan titik akhir publik KMS untuk wilayah tersebut. 
         */
        public static KmsClient getClientForPublicEndpoint(String regionId, String accessKeyId, String accessKeySecret) {
            /**
             * Konstruksi Aliyun Client:
             * Set RegionId, AccessKeyId dan AccessKeySecret
             */
            IClientProfile profile = DefaultProfile.getProfile(regionId, accessKeyId, accessKeySecret);
            DefaultAcsClient client = new DefaultAcsClient(profile);
            return new KmsClient(client);
        }
    
        /**
         * Buat klien KMS. Anda dapat menentukan alamat VPC yang digunakan untuk mengakses KMS. 
         */
        public static KmsClient getClientForVpcEndpoint(String regionId, String accessKeyId, String accessKeySecret, String endpoint) {
            // Tentukan alamat VPC.
            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);
    
            /**
             * Atur parameter sesuai dengan dokumen openAPI KMS:
             * 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. Gunakan klien KMS untuk memanggil operasi, seperti operasi untuk menghitung kunci, mengenkripsi data, dan mendekripsi data.

    Catatan
    • Dalam kode contoh berikut, akun Alibaba Cloud Anda memiliki setidaknya satu kunci master pelanggan KMS (CMK) di wilayah China (Hangzhou).

    • Metode KmsClient.getClientForPublicEndpoint mengembalikan titik akhir publik KMS.

    • Metode KmsClient.getClientForVpcEndpoint mengembalikan alamat VPC KMS.

    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("ALIBABA_CLOUD_ACCESS_KEY_ID");
            String accessKeySecret = System.getenv("ALIBABA_CLOUD_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;
    
        /*Daftar semua MasterKeys di akun Anda*/
            try {
                final ListKeysResponse listKeysRes = kmsClient.ListKey(1, 100);
    
                /**
                 * Analisis respons dan lakukan lebih banyak tindakan
                 */
                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("Daftar Semua MasterKeys berhasil!\n");
            } catch (ClientException eResponse) {
                System.out.println("Gagal.");
                System.out.println("Kode kesalahan: " + eResponse.getErrCode());
                System.out.println("Pesan kesalahan: " + eResponse.getErrMsg());
            }
    
    
            /*Jelaskan Kunci */
            try {
                final DescribeKeyResponse decKeyRes = kmsClient.DescribeKey(keyId);
    
                /**
                 * Analisis respons dan lakukan lebih banyak tindakan
                 */
                System.out.println("Respons DescribeKey: ");
                DescribeKeyResponse.KeyMetadata meta = decKeyRes.getKeyMetadata();
    
                System.out.println("KeyId: " + meta.getKeyId());
                System.out.println("Deskripsi: " + meta.getDescription());
                System.out.println("KeyState: " + meta.getKeyState());
                System.out.println("KeyUsage: " + meta.getKeyUsage());
    
                System.out.println("===========================================");
                System.out.println("Jelaskan MasterKey berhasil!");
                System.out.println("===========================================\n");
            } catch (ClientException eResponse) {
                System.out.println("Gagal.");
                System.out.println("Kode kesalahan: " + eResponse.getErrCode());
                System.out.println("Pesan kesalahan: " + eResponse.getErrMsg());
            }
    
            /*Hasilkan DataKey*/
            /**
             * Permintaan dan dapatkan respons
             */
            try {
                final GenerateDataKeyResponse genDKResponse = kmsClient.GenerateDataKey(keyId, "AES_256", 64);
    
                /**
                 * Analisis respons dan lakukan lebih banyak tindakan
                 */
                System.out.println("CiphertextBlob: " + genDKResponse.getCiphertextBlob());
                System.out.println("KeyId: " + genDKResponse.getKeyId());
                System.out.println("Plaintext: " + genDKResponse.getPlaintext());
    
                System.out.println("===========================================");
                System.out.println("Hasilkan DataKey berhasil!");
                System.out.println("===========================================\n");
            } catch (ClientException eResponse) {
                System.out.println("Gagal.");
                System.out.println("Kode kesalahan: " + eResponse.getErrCode());
                System.out.println("Pesan kesalahan: " + eResponse.getErrMsg());
            }
    
            /**
             * Enkripsi teks biasa dan dapatkan teks sandi
             */
            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("Enkripsi teks biasa berhasil!");
                System.out.println("===========================================\n");
            } catch (ClientException eResponse) {
                System.out.println("Gagal.");
                System.out.println("Kode kesalahan: " + eResponse.getErrCode());
                System.out.println("Pesan kesalahan: " + eResponse.getErrMsg());
            }
    
            /**
             * Dekripsi teks sandi dan verifikasi hasil dengan teks biasa asli.
             */
            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("Dekripsi teks sandi berhasil, hasil " + (isMatch == 0 ? "cocok" : "tidak cocok" + "\n"));
                System.out.println("===========================================\n");
            } catch (ClientException eResponse) {
                System.out.println("Gagal.");
                System.out.println("Kode kesalahan: " + eResponse.getErrCode());
                System.out.println("Pesan kesalahan: " + eResponse.getErrMsg());
            }
        }
    
     }
                

Contoh 2: Akses Secrets Manager menggunakan titik akses aplikasi berbasis kunci klien (AAP)

Jika Anda menggunakan KMS SDK untuk Java untuk mengakses Secrets Manager menggunakan AAP berbasis kunci klien, Anda dapat menggunakan kode contoh berikut.

Untuk informasi lebih lanjut, lihat Ikat Kunci Klien ke AAP.

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);
        // panggil kmsClient
    }
}

Kode contoh sebelumnya merujuk pada kode berikut untuk ClientKeyUtils dan 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() {
            // tidak melakukan apa pun
        }
    
        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 tidak valid");
                }
            }
        }
    
        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;
        }
    }