Table Store支援 V4 簽名演算法,通過衍生金鑰替代AccessKey Secret 直接參与身分識別驗證,降低密鑰泄露的影響範圍。衍生金鑰僅對特定地區和產品當天有效,次日自動失效。
V4 簽名工作原理
V4 簽名用衍生金鑰替代AccessKey Secret 直接參与身分識別驗證。衍生金鑰由AccessKey Secret、日期、地區和產品碼四個要素通過 HMAC 計算鏈推導得出:
HMAC(HMAC(HMAC(AccessKey Secret, 日期), 地區), 產品碼) → 衍生金鑰
正因如此,即使某個衍生金鑰泄露,影響也嚴格限制在特定日期、特定地區和特定產品範圍內,不會波及同帳號下其他地區或其他產品的資源。此外,衍生金鑰次日自動失效,無需手動撤銷。
使用 V4 簽名的同時,建議將AccessKey配置為環境變數,避免寫入程式碼在代碼中,進一步降低密鑰泄露風險。
請求流程
用戶端使用 V4 簽名演算法,基於AccessKey計算產生衍生金鑰,並以衍生金鑰發起請求。
服務端接收請求後,使用衍生金鑰對調用方身份進行驗證。
-
驗證通過後,服務端處理請求並返回結果。
說明驗證未通過時,服務端拒絕用戶端訪問。
用戶端接收服務端返回的處理結果。
範例程式碼
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();
}
}
}