全部產品
Search
文件中心

Tablestore:使用者密鑰安全

更新時間:Mar 15, 2025

Table Store支援採用V4簽名演算法實現對使用者密鑰的保護。在使用者身分識別驗證過程中,使用由V4簽名演算法計算產生的衍生金鑰,而非實際的使用者密鑰,從而降低密鑰泄露所引發的影響範圍。如果衍生金鑰發生泄露,其影響局限於當天某個產品下的指定地區資源,不會波及其他產品的資源及其他地區的資源。此外,衍生金鑰將在第二天自動到期不可用。

背景資訊

V4簽名提供了一種新的身份認證方式。該簽名由阿里雲帳號或RAM使用者的AccessKey Secret、日期、地區和產品碼四個資訊通過特定方式計算得到的字串構成。

使用V4簽名後,如果某一個V4簽名被竊取,則該帳號下其他地區、其他產品不會受到影響,並且被竊取的V4簽名有效期間不超過一天。因此使用V4簽名可以保證使用者的帳號密鑰安全。

說明

除了V4簽名功能外,在日常業務中使用使用者密鑰時,請務必妥善保管該密鑰。例如,在代碼中將密鑰配置為環境變數之後再使用。

請求流程

  1. 在用戶端使用V4簽名演算法對使用者密鑰進行計算產生衍生金鑰,並使用衍生金鑰發起請求。

  2. 服務端接收到請求時,使用衍生金鑰進行使用者身分識別驗證。

  3. 使用者身分識別驗證通過後,服務端處理請求並返回處理結果。

    說明

    如果使用者身分識別驗證未通過,則服務端會拒絕用戶端訪問。

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

範例程式碼

重要

Table StoreJava SDK從5.16.1版本開始支援V4簽名功能。使用V4簽名前,請確保您已使用支援該功能的SDK版本。

使用AccessKey初始化

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

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

  • 在樣本1中,使用者僅需提供存取金鑰(AccessKey),由Tablestore SDK計算生產衍生金鑰。使用者無需手動維護衍生金鑰,當衍生金鑰到期後,Tablestore 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臨時訪問憑據,由Tablestore SDK計算生產衍生金鑰。使用者無需手動維護衍生金鑰,當衍生金鑰到期後,Tablestore 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();
        }
    }
}