全部產品
Search
文件中心

Key Management Service:加密解密樣本

更新時間:Dec 26, 2024

初始化KMS執行個體SDK用戶端後,您可以通過用戶端調用Encrypt和Decrypt介面對資料進行加密解密。本文介紹加密解密的程式碼範例。

完整程式碼範例

整合KMS進行對稱式加密解密包含三個步驟:

  1. 初始化調用KMS介面的用戶端。

  2. 使用用戶端調用Encrypt介面對資料進行加密。

  3. 使用用戶端調用Decrypt介面對密文資料進行解密。

源碼github地址:AesEncryptDecryptSample.java

加密解密完整程式碼範例

package com.aliyun.dkms.gcs.sdk.example;

import com.aliyun.dkms.gcs.openapi.models.Config;
import com.aliyun.dkms.gcs.openapi.util.models.RuntimeOptions;
import com.aliyun.dkms.gcs.sdk.Client;
import com.aliyun.dkms.gcs.sdk.models.DecryptRequest;
import com.aliyun.dkms.gcs.sdk.models.DecryptResponse;
import com.aliyun.dkms.gcs.sdk.models.EncryptRequest;
import com.aliyun.dkms.gcs.sdk.models.EncryptResponse;
import com.aliyun.tea.TeaException;

import java.io.Serializable;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;

/**
 * ClientKey傳參支援以下三種方式:
 * 1、通過指定ClientKey.json檔案路徑方式
 * 樣本:
 * String clientKeyFile = "<your client key file path>";
 * String password = "<your client key password>";
 * Config cfg = new Config();
 * cfg.setClientKeyFile(clientKeyFile);
 * cfg.setPassword(password);
 * <p>
 * 2、通過指定ClientKey內容方式
 * 樣本:
 * String clientKeyContent = "<your client key content>";
 * String password = "<your client key password>";
 * Config cfg = new Config();
 * cfg.setClientKeyContent(clientKeyContent);
 * cfg.setPassword(password);
 * <p>
 * 3、通過指定私密金鑰和AccessKeyId
 * 樣本:
 * String accessKeyId = "<your client key KeyId>";
 * String privateKey = "<parse from your client key PrivateKeyData>";
 * Config cfg = new Config();
 * cfg.setAccessKeyId(accessKeyId);
 * cfg.setPrivateKey(privateKey);
 */
public class AesEncryptDecryptSample {

    // KMS執行個體Client對象
    private static Client client = null;

    public static void main(String[] args) {
        try {
            // 構建Data Encryption Service執行個體Client對象
            initClient();

            // 使用Data Encryption Service執行個體進行加解密樣本
            encryptDecryptSample();

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void initClient() throws Exception {
        // 連線協定請設定為"https"。KMS執行個體服務僅允許通過HTTPS協議訪問。
        Config config = new Config();
        config.setProtocol("https");
    
        // Client Key。
        config.setClientKeyFile("<your-client-key-file>");
     
         // Client Key口令。
        config.setPassword("<your-password>");
       
         // 設定endpoint為<your KMS Instance Id>.cryptoservice.kms.aliyuncs.com。
        config.setEndpoint("<your-endpoint>");
        
        // KMS執行個體的CA認證,可通過檔案路徑或直接設定內容。
        config.setCaFilePath("<path/to/yourCaCert>");
        // 或者,設定為KMS執行個體的CA認證內容
        //config.setCa("<your-ca-certificate-content");
        client = new Client(config);
    }

    // 加解密樣本
    private static void encryptDecryptSample() {
        String keyId = "<your-key-id>";
        String plaintext = "<your-plaintext>";
        final AesEncryptContext aesEncryptContext = encryptSample(keyId, plaintext);
        String decryptResult = decryptSample(aesEncryptContext);
        if (!plaintext.equals(decryptResult)) {
            System.out.println("Decrypt data not match the plaintext");
        }
    }

    // 加密樣本
    private static AesEncryptContext encryptSample(String keyId, String plaintext) {
        // 構建加密請求
        EncryptRequest encryptRequest = new EncryptRequest();
        encryptRequest.setKeyId(keyId);
        encryptRequest.setPlaintext(plaintext.getBytes(StandardCharsets.UTF_8));
        try {
            // 調用加密介面進行加密
            // 如需忽略服務端認證,可使用此處注釋代碼方式調用
            //RuntimeOptions runtimeOptions = new RuntimeOptions();
            //runtimeOptions.setIgnoreSSL(true);
            //EncryptResponse encryptResponse = client.encryptWithOptions(encryptRequest, runtimeOptions);
            EncryptResponse encryptResponse = client.encrypt(encryptRequest);
            System.out.printf("KeyId: %s%n", encryptResponse.getKeyId());
            System.out.printf("CiphertextBlob: %s%n", Arrays.toString(encryptResponse.getCiphertextBlob()));
            System.out.printf("Iv: %s%n", Arrays.toString(encryptResponse.getIv()));
            return new AesEncryptContext(encryptResponse.getKeyId(), encryptResponse.getCiphertextBlob(), encryptResponse.getIv(), encryptResponse.getAlgorithm());
        } catch (TeaException e) {
            System.out.printf("code: %s%n", ((TeaException) e).getCode());
            System.out.printf("message: %s%n", e.getMessage());
            System.out.printf("requestId: %s%n", ((TeaException) e).getData().get("requestId"));
            e.printStackTrace();
            throw new RuntimeException(e);
        } catch (Exception e) {
            System.out.printf("encrypt err: %s%n", e.getMessage());
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }

    // 解密樣本
    private static String decryptSample(final AesEncryptContext aesEncryptContext) {
        // 構建解密請求對象
        DecryptRequest decryptRequest = new DecryptRequest();
        decryptRequest.setKeyId(aesEncryptContext.getKeyId());
        decryptRequest.setCiphertextBlob(aesEncryptContext.getCiphertextBlob());
        decryptRequest.setAlgorithm(aesEncryptContext.getAlgorithm());
        decryptRequest.setIv(aesEncryptContext.getIv());
        try {
            // 調用解密介面進行解密
            // 如需忽略服務端認證,可使用此處注釋代碼方式調用
            //RuntimeOptions runtimeOptions = new RuntimeOptions();
            //runtimeOptions.setIgnoreSSL(true);
            //DecryptResponse decryptResponse = client.decryptWithOptions(decryptRequest, runtimeOptions);
            DecryptResponse decryptResponse = client.decrypt(decryptRequest);
            System.out.printf("KeyId: %s%n", decryptResponse.getKeyId());
            System.out.printf("Plaintext: %s%n", new String(decryptResponse.getPlaintext()));
            System.out.printf("RequestId: %s%n", decryptResponse.getRequestId());
            return new String(decryptResponse.getPlaintext());
        } catch (TeaException e) {
            System.out.printf("code: %s%n", ((TeaException) e).getCode());
            System.out.printf("message: %s%n", e.getMessage());
            System.out.printf("requestId: %s%n", ((TeaException) e).getData().get("requestId"));
            e.printStackTrace();
            throw new RuntimeException(e);
        } catch (Exception e) {
            System.out.printf("decrypt err: %s%n", e.getMessage());
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }

    /**
     * The aes encrypt context may be stored.
     */
    static class AesEncryptContext implements Serializable {
        public String keyId;
        public byte[] ciphertextBlob;
        public byte[] iv;
        /**
         * Use default algorithm value,if the value is not set.
         */
        public String algorithm;

        public AesEncryptContext() {
        }

        public AesEncryptContext(String keyId, byte[] ciphertextBlob, byte[] iv, String algorithm) {
            this.keyId = keyId;
            this.ciphertextBlob = ciphertextBlob;
            this.iv = iv;
            this.algorithm = algorithm;
        }

        public String getKeyId() {
            return keyId;
        }

        public void setKeyId(String keyId) {
            this.keyId = keyId;
        }

        public byte[] getCiphertextBlob() {
            return ciphertextBlob;
        }

        public void setCiphertextBlob(byte[] ciphertextBlob) {
            this.ciphertextBlob = ciphertextBlob;
        }

        public byte[] getIv() {
            return iv;
        }

        public void setIv(byte[] iv) {
            this.iv = iv;
        }

        public String getAlgorithm() {
            return algorithm;
        }

        public void setAlgorithm(String algorithm) {
            this.algorithm = algorithm;
        }

    }
}

程式碼範例解析

初始化用戶端

關於初始化用戶端的詳細介紹,請參見初始化用戶端

import com.aliyun.dkms.gcs.openapi.models.Config;
import com.aliyun.dkms.gcs.sdk.Client;

                           
 public static void initClient() throws Exception {

        // 連線協定請設定為"https"。KMS執行個體服務僅允許通過HTTPS協議訪問。
        Config config = new Config();
        config.setProtocol("https");
    
        // Client Key。
        config.setClientKeyFile("<your-client-key-file>");
     
         // Client Key口令。
        config.setPassword("<your-password>");
       
         // 設定endpoint為<your KMS Instance Id>.cryptoservice.kms.aliyuncs.com。
        config.setEndpoint("<your-endpoint>");
        
        // KMS執行個體的CA認證,可通過檔案路徑或直接設定內容。
        config.setCaFilePath("<path/to/yourCaCert>");
        // 或者,設定為KMS執行個體的CA認證內容
        //config.setCa("<your-ca-certificate-content");
        client = new Client(config);
    }

調用Encrypt介面使用對稱金鑰對資料加密

您調用Encrypt進行資料加密後,除需要儲存資料密文(CiphertextBlob),還需要儲存KMS返回的密鑰ID(KeyId)、Iv、密碼編譯演算法(Algorithm)參數。

 // 加密樣本
    private static AesEncryptContext encryptSample(String keyId, String plaintext) {
        // 構建加密請求
        EncryptRequest encryptRequest = new EncryptRequest();
        encryptRequest.setKeyId(keyId);
        encryptRequest.setPlaintext(plaintext.getBytes(StandardCharsets.UTF_8));
        try {
            // 調用加密介面進行加密
            // 如需忽略服務端認證,可使用此處注釋代碼方式調用
            //RuntimeOptions runtimeOptions = new RuntimeOptions();
            //runtimeOptions.setIgnoreSSL(true);
            //EncryptResponse encryptResponse = client.encryptWithOptions(encryptRequest, runtimeOptions);
            EncryptResponse encryptResponse = client.encrypt(encryptRequest);
            System.out.printf("KeyId: %s%n", encryptResponse.getKeyId());
            System.out.printf("CiphertextBlob: %s%n", Arrays.toString(encryptResponse.getCiphertextBlob()));
            System.out.printf("Iv: %s%n", Arrays.toString(encryptResponse.getIv()));
            return new AesEncryptContext(encryptResponse.getKeyId(), encryptResponse.getCiphertextBlob(), encryptResponse.getIv(), encryptResponse.getAlgorithm());
        } catch (TeaException e) {
            System.out.printf("code: %s%n", ((TeaException) e).getCode());
            System.out.printf("message: %s%n", e.getMessage());
            System.out.printf("requestId: %s%n", ((TeaException) e).getData().get("requestId"));
            e.printStackTrace();
            throw new RuntimeException(e);
        } catch (Exception e) {
            System.out.printf("encrypt err: %s%n", e.getMessage());
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }

調用Decrypt介面使用對稱金鑰解密密文

     // 解密樣本
    private static String decryptSample(final AesEncryptContext aesEncryptContext) {
        // 構建解密請求對象
        DecryptRequest decryptRequest = new DecryptRequest();
        decryptRequest.setKeyId(aesEncryptContext.getKeyId());
        decryptRequest.setCiphertextBlob(aesEncryptContext.getCiphertextBlob());
        decryptRequest.setAlgorithm(aesEncryptContext.getAlgorithm());
        decryptRequest.setIv(aesEncryptContext.getIv());
        try {
            // 調用解密介面進行解密
            // 如需忽略服務端認證,可使用此處注釋代碼方式調用
            //RuntimeOptions runtimeOptions = new RuntimeOptions();
            //runtimeOptions.setIgnoreSSL(true);
            //DecryptResponse decryptResponse = client.decryptWithOptions(decryptRequest, runtimeOptions);
            DecryptResponse decryptResponse = client.decrypt(decryptRequest);
            System.out.printf("KeyId: %s%n", decryptResponse.getKeyId());
            System.out.printf("Plaintext: %s%n", new String(decryptResponse.getPlaintext()));
            System.out.printf("RequestId: %s%n", decryptResponse.getRequestId());
            return new String(decryptResponse.getPlaintext());
        } catch (TeaException e) {
            System.out.printf("code: %s%n", ((TeaException) e).getCode());
            System.out.printf("message: %s%n", e.getMessage());
            System.out.printf("requestId: %s%n", ((TeaException) e).getData().get("requestId"));
            e.printStackTrace();
            throw new RuntimeException(e);
        } catch (Exception e) {
            System.out.printf("decrypt err: %s%n", e.getMessage());
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }