全部產品
Search
文件中心

Tablestore:使用者密鑰安全

更新時間:Apr 30, 2026

Table Store支援 V4 簽名演算法,通過衍生金鑰替代AccessKey Secret 直接參与身分識別驗證,降低密鑰泄露的影響範圍。衍生金鑰僅對特定地區和產品當天有效,次日自動失效。

V4 簽名工作原理

V4 簽名用衍生金鑰替代AccessKey Secret 直接參与身分識別驗證。衍生金鑰由AccessKey Secret、日期、地區和產品碼四個要素通過 HMAC 計算鏈推導得出:

HMAC(HMAC(HMAC(AccessKey Secret, 日期), 地區), 產品碼) → 衍生金鑰

正因如此,即使某個衍生金鑰泄露,影響也嚴格限制在特定日期、特定地區和特定產品範圍內,不會波及同帳號下其他地區或其他產品的資源。此外,衍生金鑰次日自動失效,無需手動撤銷。

說明

使用 V4 簽名的同時,建議將AccessKey配置為環境變數,避免寫入程式碼在代碼中,進一步降低密鑰泄露風險。

請求流程

  1. 用戶端使用 V4 簽名演算法,基於AccessKey計算產生衍生金鑰,並以衍生金鑰發起請求。

  2. 服務端接收請求後,使用衍生金鑰對調用方身份進行驗證。

  3. 驗證通過後,服務端處理請求並返回結果。

    說明

    驗證未通過時,服務端拒絕用戶端訪問。

  4. 用戶端接收服務端返回的處理結果。

範例程式碼

重要

Table Store Java SDK 5.16.1 及以上版本支援 V4 簽名功能。使用前請確認SDK版本滿足要求。

使用AccessKey初始化

以下樣本以阿里雲帳號或RAM使用者的AccessKey為例介紹如何配置訪問憑證。AccessKey 的擷取方式,請參見 如何擷取AccessKey

以下範例程式碼使用 V4 簽名初始化 Tablestore Client,擷取執行個體下的資料表列表並列印到控制台。

  • 樣本 1(推薦):僅需提供 AccessKey,衍生金鑰由SDK自動計算和重新整理,無需手動維護。

  • 樣本 2:同時提供AccessKey與衍生金鑰(v4SigningAccessKey)。衍生金鑰次日自動失效,必須自行實現定時重新整理機制,否則到期後將無法訪問Table Store服務。

import com.alicloud.openservices.tablestore.SyncClient;
import com.alicloud.openservices.tablestore.core.ResourceManager;
import com.alicloud.openservices.tablestore.core.auth.*;
import java.text.SimpleDateFormat;
import java.util.Date;
import static com.alicloud.openservices.tablestore.core.Constants.PRODUCT;
import static com.alicloud.openservices.tablestore.core.Constants.SIGNING_KEY_SIGN_METHOD;

public class InitClientV4 {
    public static void main(String[] args) {
        // yourRegion 填寫您的執行個體所在地區,如 cn-hangzhou
        final String region = "yourRegion";
        // yourInstanceName 填寫您的執行個體名稱
        final String instanceName = "yourInstanceName";
        // yourEndpoint 填寫您的執行個體訪問地址
        final String endpoint = "yourEndpoint";
        // 擷取系統變數裡的 AccessKey ID 和 AccessKey Secret
        final String accessKeyId = System.getenv("TABLESTORE_ACCESS_KEY_ID");
        final String accessKeySecret = System.getenv("TABLESTORE_ACCESS_KEY_SECRET");

        {
            /**
             * 樣本一:使用原始的accessKeyId,accessKeySecret -> 先構造{@link DefaultCredentials },再產生 {@link V4Credentials }
             */
            DefaultCredentials credentials = new DefaultCredentials(accessKeyId, accessKeySecret);
            V4Credentials credentialsV4 = V4Credentials.createByServiceCredentials(credentials, region);
            CredentialsProvider provider = new DefaultCredentialProvider(credentialsV4);

            /**
             * using {@link V4Credentials } initialize tableStore client
             */
            SyncClient client = new SyncClient(endpoint, provider, instanceName, null, new ResourceManager(null, null));

            // do something
            client.listTable().getTableNames().forEach(System.out::println);
            // shutdown tableStore client
            client.shutdown();
        }

        {
            /**
             * 樣本二:直接使用accessKey與衍生金鑰 -> 直接構造{@link V4Credentials }
             */
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
            String signDate = dateFormat.format(new Date()); // signDate格式如同"20230527"
            String v4SigningAccessKey = CalculateV4SigningKeyUtil.finalSigningKeyString(accessKeySecret, signDate, region, PRODUCT, SIGNING_KEY_SIGN_METHOD); // 衍生金鑰
            V4Credentials credentialsV4 = new V4Credentials(accessKeyId, v4SigningAccessKey, region, signDate);
            CredentialsProvider provider = new DefaultCredentialProvider(credentialsV4);

            /**
             * using {@link V4Credentials } initialize tableStore client
             */
            SyncClient client = new SyncClient(endpoint, provider, instanceName, null, new ResourceManager(null, null));

            // do something
            client.listTable().getTableNames().forEach(System.out::println);
            // shutdown tableStore client
            client.shutdown();
        }
    }
}

使用STS初始化

如何擷取 STS 臨時訪問憑證,請參見 使用STS臨時訪問憑證訪問Table Store

以下範例程式碼使用 V4 簽名初始化 Tablestore Client,擷取執行個體下的資料表列表並列印到控制台。

  • 樣本 1(推薦):僅需提供 STS 臨時訪問憑證,衍生金鑰由SDK自動計算和重新整理,無需手動維護。

  • 樣本 2:同時提供 STS 臨時訪問憑證與衍生金鑰(v4SigningAccessKey)。衍生金鑰次日自動失效,必須自行實現定時重新整理機制,否則到期後將無法訪問Table Store服務。

import com.alicloud.openservices.tablestore.SyncClient;
import com.alicloud.openservices.tablestore.core.ResourceManager;
import com.alicloud.openservices.tablestore.core.auth.*;
import java.text.SimpleDateFormat;
import java.util.Date;
import static com.alicloud.openservices.tablestore.core.Constants.PRODUCT;
import static com.alicloud.openservices.tablestore.core.Constants.SIGNING_KEY_SIGN_METHOD;

public class InitClientV4 {
    public static void main(String[] args) {
        // yourRegion 填寫您的執行個體所在地區,如 cn-hangzhou
        final String region = "yourRegion";
        // yourInstanceName 填寫您的執行個體名稱
        final String instanceName = "yourInstanceName";
        // yourEndpoint 填寫您的執行個體訪問地址
        final String endpoint = "yourEndpoint";
        // 擷取環境變數裡的 STS AccessKey ID、STS AccessKey Secret 和 STS Token
        final String accessKeyId = System.getenv("TABLESTORE_ACCESS_KEY_ID");
        final String accessKeySecret = System.getenv("TABLESTORE_ACCESS_KEY_SECRET");
        final String securityToken = System.getenv("TABLESTORE_SESSION_TOKEN");

        {
            /**
             *  樣本一:使用原始的accessKeyId,accessKeySecret,securityToken -> 先構造{@link DefaultCredentials },再產生 {@link V4Credentials }
             */
            DefaultCredentials credentials = new DefaultCredentials(accessKeyId, accessKeySecret, securityToken);
            V4Credentials credentialsV4 = V4Credentials.createByServiceCredentials(credentials, region);
            CredentialsProvider provider = new DefaultCredentialProvider(credentialsV4);

            /**
             * using {@link V4Credentials } initialize tableStore client
             */
            SyncClient client = new SyncClient(endpoint, provider, instanceName, null, new ResourceManager(null, null));

            // do something
            client.listTable().getTableNames().forEach(System.out::println);
            // shutdown tableStore client
            client.shutdown();
        }
        
        {
            /**
             * 樣本二:直接使用accessKey與衍生金鑰 -> 直接構造{@link V4Credentials }
             */
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
            String signDate = dateFormat.format(new Date());      // signDate格式如同"20230527"
            String v4SigningAccessKey = CalculateV4SigningKeyUtil.finalSigningKeyString(accessKeySecret, signDate, region, PRODUCT, SIGNING_KEY_SIGN_METHOD);
            V4Credentials credentialsV4 = new V4Credentials(accessKeyId, v4SigningAccessKey, securityToken, region, signDate);
            CredentialsProvider provider = new DefaultCredentialProvider(credentialsV4);

            /**
             * using {@link V4Credentials } initialize tableStore client
             */
            SyncClient client = new SyncClient(endpoint, provider, instanceName, null, new ResourceManager(null, null));

            // do something
            client.listTable().getTableNames().forEach(System.out::println);
            // shutdown tableStore client
            client.shutdown();
        }
    }
}