全部產品
Search
文件中心

Key Management Service:使用KMS密鑰線上加密和解密資料

更新時間:Feb 28, 2026

在部署於阿里雲或其他雲環境的公網IP資產中,敏感性資料需要安全儲存與傳輸以降低泄露風險並滿足合規要求。針對體量較小的敏感性資料對象,可直接通過Key Management Service(KMS)線上執行加密與解密操作。本文介紹線上加解密的使用情境、前置條件及具體操作步驟。

適用範圍

  • 單次使用對稱金鑰加解密的資料不超過6 KB。

  • 單次使用非對稱金鑰加解密的資料不超過1KB。

說明

單次加密的資料量越大,網路傳輸失敗可能性越大,網路傳輸所需時間越長,KMS執行個體對資料進行加解密所需時間也越長。

準備工作

在開始調用API進行加解密前,請完成以下準備工作。

步驟一:購買並啟用KMS執行個體

請根據業務需求和安全合規要求,購買並啟用一個KMS執行個體(軟體密鑰管理執行個體和硬體密鑰管理執行個體)。具體操作,請參見購買和啟用KMS執行個體

步驟二:建立密鑰

根據加密情境,在已啟用的KMS執行個體中建立相應的密鑰。

  • 對稱金鑰:用於在信任環境內進行加解密。

  • 非對稱金鑰:用於跨信任環境的情境,例如用戶端使用公開金鑰加密,服務端使用私密金鑰解密。

具體操作,請參見建立密鑰

步驟三:準備訪問憑證與許可權

本文以AccessKey方式為例,更多訪問憑證說明,請參見建立訪問憑證

重要

為確保賬戶安全,切勿使用擁有最高許可權的主帳號AccessKey。應建立並使用具有最小必要許可權的RAM使用者AccessKey進行API訪問。如何建立RAM使用者,請參見建立RAM使用者

  1. 為確保賬戶安全,官方建議建立並使用具有最小必要許可權的RAM使用者AccessKey,而不是使用主帳號的AccessKey進行API訪問。

    1. 登入 RAM控制台建立RAM使用者

    2. 為建立的RAM使用者建立AccessKey

      1. RAM控制台使用者頁面,單擊目標RAM使用者名稱稱。

      2. 認證管理 頁簽下的 AccessKey 地區,單擊建立AccessKey,並按照指引完成建立。

        重要

        請妥善保管您的AccessKey ID和Secret。

    3. 為RAM使用者授予調用KMS進行加解密的最小許可權。

      • 方式一:設定基於身份的策略

        • KMS內建了系統權限原則,可以直接綁定到RAM使用者,詳細介紹,請參見Key Management Service系統權限原則參考

        • 也可以自訂權限原則。以下樣本表示可使用key-hzz65f17868e6cl0n****下,建立的對稱金鑰和非對稱金鑰進行加解密。

          {
            "Version": "1",
            "Statement": [
              {
                "Effect": "Allow",
                "Action": [
                  "kms:Encrypt",
                  "kms:Decrypt",
                  "kms:AsymmetricEncrypt",
                  "kms:AsymmetricDecrypt"
                ],
                "Resource": [
                  "acs:kms:*:*:key/key-hzz65f17868e6cl0n****"
                ]
              }
            ]
          }

        image

      • 方式二:設定基於資源的策略

        KMS支援基於資源的策略,即為單個密鑰和憑據設定存取權限,用於控制哪些阿里雲帳號、RAM使用者、RAM角色有許可權來管理或使用KMS密鑰、憑據。詳細介紹,請參見密鑰策略憑據策略

步驟四:擷取串連資訊和CA認證

調用API時,需要根據網路環境選擇合適的網關地址(Endpoint)。

說明

本文樣本預設使用專屬網關

特性

共用網關

專屬網關

Endpoint

kms.<RegionId>.aliyuncs.com

<YOUR_KMS_INSTANCE_ID>.cryptoservice.kms.aliyuncs.com

CA認證

無需配置。

必須配置。

適用情境

公網訪問、開發測試。

VPC內網訪問、生產環境、更高效能和隔離性。

擷取方式

具體請參見Endpoint

在執行個體的詳情頁面,下載執行個體CA認證,並擷取執行個體VPC地址

應用情境

情境一:應用部署在阿里雲上

阿里雲上部署的應用服務會產生或收到明文形式的敏感性資料,敏感性資料需要加密後再通過資料庫等方式儲存,該情境推薦使用對稱式加密演算法。

相關API

API名稱

說明

Encrypt

使用對稱主要金鑰加密明文

Decrypt

使用對稱金鑰進行解密。

範例程式碼

加密資料 (Encrypt)

以下範例程式碼示範了如何調用 Encrypt 介面,使用對稱金鑰將明文加密成密文。

package com.aliyun.sample;

import com.aliyun.kms20160120.Client;
import com.aliyun.kms20160120.models.EncryptRequest;
import com.aliyun.kms20160120.models.EncryptResponse;
import com.aliyun.teaopenapi.models.Config;
import com.aliyun.teautil.models.RuntimeOptions;
import java.nio.charset.StandardCharsets;

public class SymmetricEncryptSample {

    public static Client createClient() throws Exception {
        // 使用環境變數中擷取的AccessKey ID和AccessKey Secret初始化Client。
        // 請確保代碼運行環境已設定環境變數 ALIBABA_CLOUD_ACCESS_KEY_ID 和 ALIBABA_CLOUD_ACCESS_KEY_SECRET。
        Config config = new Config()
                .setAccessKeyId(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"))
                .setAccessKeySecret(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"));
        
        // 設定專屬網關Endpoint。
        config.endpoint = "<Your-KMS-Instance-Endpoint>"; 
        // 設定KMS執行個體的CA認證內容。
        config.ca = "<Your-CA-Certificate-Content>";
        
        return new Client(config);
    }

    public static void main(String[] args) throws Exception {
        Client client = createClient();
        
        // 待加密的明文。
        String plaintext = "this is a test message.";
        
        EncryptRequest encryptRequest = new EncryptRequest()
                // 設定要使用的對稱金鑰ID。
                .setKeyId("<Your-Symmetric-Key-Id>")
                // 設定待加密的明文。Plaintext需為位元組數組,SDK會自動進行Base64編碼。
                .setPlaintext(plaintext.getBytes(StandardCharsets.UTF_8));

        try {
            // 調用Encrypt介面。
            EncryptResponse response = client.encryptWithOptions(encryptRequest, new RuntimeOptions());
            
            // 從響應中擷取Base64編碼的密文。
            String ciphertextBlob = response.getBody().getCiphertextBlob();
            
            System.out.println("Plaintext: " + plaintext);
            System.out.println("Ciphertext (Base64): " + ciphertextBlob);

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

解密資料 (Decrypt)

以下範例程式碼示範了如何調用 Decrypt 介面,將密文解密成明文。

package com.aliyun.sample;

import com.aliyun.kms20160120.Client;
import com.aliyun.kms20160120.models.DecryptRequest;
import com.aliyun.kms20160120.models.DecryptResponse;
import com.aliyun.teaopenapi.models.Config;
import com.aliyun.teautil.models.RuntimeOptions;
import java.nio.charset.StandardCharsets;

public class SymmetricDecryptSample {

    public static Client createClient() throws Exception {
        // Client初始化邏輯同加密樣本。
        Config config = new Config()
                .setAccessKeyId(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"))
                .setAccessKeySecret(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"));
        config.endpoint = "<Your-KMS-Instance-Endpoint>";
        config.ca = "<Your-CA-Certificate-Content>";
        return new Client(config);
    }

    public static void main(String[] args) throws Exception {
        Client client = createClient();
        
        // 待解密的密文,必須是來自Encrypt介面返回的Base64編碼字串。
        String ciphertextBlob = "<Ciphertext-From-Encryption-Step>";
        
        DecryptRequest decryptRequest = new DecryptRequest()
                // 設定待解密的密文。
                .setCiphertextBlob(ciphertextBlob);

        try {
            // 調用Decrypt介面。
            DecryptResponse response = client.decryptWithOptions(decryptRequest, new RuntimeOptions());
            
            // 從響應中擷取解密後的明文位元組數組。
            byte[] plaintextBytes = response.getBody().getPlaintext().getBytes();
            
            // 根據業務需要將位元組數群組轉換為字串。
            String plaintext = new String(plaintextBytes, StandardCharsets.UTF_8);
            
            System.out.println("Ciphertext (Base64): " + ciphertextBlob);
            System.out.println("Decrypted Plaintext: " + plaintext);

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

情境二:應用部署在阿里雲上和阿里雲外

推薦使用非對稱式加密演算法,實現雲外加密、雲上解密的業務情境。

  • 雲外應用使用公開金鑰加密資料,並將密文傳輸至雲上應用。

  • 雲上應用接收到密文後,調用KMS執行個體通過私密金鑰完成解密。

相關API

API名稱

說明

AsymmetricEncrypt

使用非對稱金鑰進行加密。

AsymmetricDecrypt

使用非對稱金鑰進行解密。

範例程式碼

加密

package com.aliyun.sample;

import com.aliyun.tea.*;

public class Sample {

    /**
     * <b>description</b> :
     * <p>使用憑據初始化帳號Client</p>
     * @return Client
     * 
     * @throws Exception
     */
    public static com.aliyun.kms20160120.Client createClient() throws Exception {
        // 工程代碼建議使用更安全的無AK方式,憑據配置方式請參見:https://www.alibabacloud.com/help/document_detail/378657.html。
         com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config()
                // 必填,請確保代碼運行環境設定了環境變數 ALIBABA_CLOUD_ACCESS_KEY_ID。
                .setAccessKeyId(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"))
                // 必填,請確保代碼運行環境設定了環境變數 ALIBABA_CLOUD_ACCESS_KEY_SECRET。
                .setAccessKeySecret(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"));
        config.endpoint = "kst-hzz65f176a0ogplgq****.cryptoservice.kms.aliyuncs.com";
        //KMS執行個體CA認證
        config.ca = "-----BEGIN CERTIFICATE-----MIIDuzCCAqOgAwIBAgIJALTKwWAjvbMiMA0GCS****";
        return new com.aliyun.kms20160120.Client(config);
    }

    public static void main(String[] args) throws Exception {    
        com.aliyun.kms20160120.Client client = Sample.createClient();
         com.aliyun.kms20160120.models.AsymmetricEncryptRequest asymmetricEncryptRequest = new com.aliyun.kms20160120.models.AsymmetricEncryptRequest()
                .setPlaintext("test")
                .setKeyId("a06e2410-*****-330777ee1825")
                .setKeyVersionId("key-hzz65f17868e6cl0n****")
                .setAlgorithm("RSAES_OAEP_SHA_256");
        com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();
        try {
            com.aliyun.kms20160120.models.AsymmetricEncryptResponse resp = client.asymmetricEncryptWithOptions(asymmetricEncryptRequest, runtime);
            System.out.println(new com.google.gson.Gson().toJson(resp));
        } catch (TeaException error) {
            // 此處僅做列印展示,請謹慎對待異常處理,在工程專案中切勿直接忽略異常。
            // 錯誤 message
            System.out.println(error.getMessage());
            // 診斷地址
            System.out.println(error.getData().get("Recommend"));
        } catch (Exception _error) {
            TeaException error = new TeaException(_error.getMessage(), _error);
            // 此處僅做列印展示,請謹慎對待異常處理,在工程專案中切勿直接忽略異常。
            // 錯誤 message
            System.out.println(error.getMessage());
            // 診斷地址
            System.out.println(error.getData().get("Recommend"));
        }        
    }
}

解密

public class Sample {
 
    /**
     * <b>description</b> :
     * <p>使用憑據初始化帳號Client</p>
     * @return Client
     * 
     * @throws Exception
     */
    public static com.aliyun.kms20160120.Client createClient() throws Exception {
       // 工程代碼泄露可能會導致 AccessKey 泄露,並威脅帳號下所有資源的安全性。以下程式碼範例僅供參考。
        com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config()
                // 必填,請確保代碼運行環境設定了環境變數 ALIBABA_CLOUD_ACCESS_KEY_ID。
                .setAccessKeyId(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"))
                // 必填,請確保代碼運行環境設定了環境變數 ALIBABA_CLOUD_ACCESS_KEY_SECRET。
                .setAccessKeySecret(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"));
        // 專屬網關Endpoint 
        config.endpoint = "kst-hzz65f176a0ogplgq****.cryptoservice.kms.aliyuncs.com";
        //KMS執行個體CA認證
        config.ca = "-----BEGIN CERTIFICATE-----MIIDuzCCAqOgAwIBAgIJALTKwWAjvbMiMA0GCS****";
        return new com.aliyun.kms20160120.Client(config);
    }
 
    public static void main(String[] args_) throws Exception {
        
       public static void main(String[] args_) throws Exception {
        
        com.aliyun.kms20160120.Client client = Sample.createClient();
        com.aliyun.kms20160120.models.AsymmetricDecryptRequest asymmetricDecryptRequest = new com.aliyun.kms20160120.models.AsymmetricDecryptRequest()
                .setKeyId("a06e2410-*****-330777ee1825")
                .setKeyVersionId("key-hzz65f17868e6cl0n****")
                .setAlgorithm("RSAES_OAEP_SHA_256")
                .setCiphertextBlob("FV9i23PQdpGPvc*********MA==");
        com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();
        try {
            com.aliyun.kms20160120.models.AsymmetricDecryptResponse resp = client.asymmetricDecryptWithOptions(asymmetricDecryptRequest, runtime);
            System.out.println(new com.google.gson.Gson().toJson(resp));
        } catch (TeaException error) {
            // 此處僅做列印展示,請謹慎對待異常處理,在工程專案中切勿直接忽略異常。
            // 錯誤 message
            System.out.println(error.getMessage());
            // 診斷地址
            System.out.println(error.getData().get("Recommend"));
        } catch (Exception _error) {
            TeaException error = new TeaException(_error.getMessage(), _error);
            // 此處僅做列印展示,請謹慎對待異常處理,在工程專案中切勿直接忽略異常。
            // 錯誤 message
            System.out.println(error.getMessage());
            // 診斷地址
            System.out.println(error.getData().get("Recommend"));
        }        
    }
}