用户密钥安全

更新时间:2025-03-14 05:01:55

表格存储支持采用V4签名算法实现对用户密钥的保护。在用户身份验证过程中,使用由V4签名算法计算生成的派生密钥,而非实际的用户密钥,从而降低密钥泄露所引发的影响范围。如果派生密钥发生泄露,其影响局限于当天某个产品下的指定地域资源,不会波及其他产品的资源及其他地域的资源。此外,派生密钥将在第二天自动过期不可用。

背景信息

V4签名提供了一种新的身份认证方式。该签名由阿里云账号或RAM用户的AccessKey Secret、日期、地域和产品码四个信息通过特定方式计算得到的字符串构成。

使用V4签名后,如果某一个V4签名被窃取,则该账号下其他地域、其他产品不会受到影响,并且被窃取的V4签名有效期不超过一天。因此使用V4签名可以保证用户的账号密钥安全。

说明

除了V4签名功能外,在日常业务中使用用户密钥时,请务必妥善保管该密钥。例如,在代码中将密钥配置为环境变量之后再使用。

请求流程

  1. 在客户端使用V4签名算法对用户密钥进行计算生成派生密钥,并使用派生密钥发起请求。

  2. 服务端接收到请求时,使用派生密钥进行用户身份验证。

  3. 用户身份验证通过后,服务端处理请求并返回处理结果。

    说明

    如果用户身份验证未通过,则服务端会拒绝客户端访问。

  4. 客户端收到服务端返回的处理结果。

示例代码

重要

表格存储Java SDK5.16.1版本开始支持V4签名功能。使用V4签名前,请确保您已使用支持该功能的SDK版本。

使用AccessKey初始化
使用STS初始化
此处以阿里云账号或RAM用户的AccessKey为例为您介绍如何配置访问凭证。AccessKey的获取方式,请参见如何获取AccessKey

以下示例代码使用V4签名初始化Tablestore Client,获取实例下的数据表列表并打印到控制台。

  • 在示例1中,用户仅需提供访问密钥(AccessKey),由Tablestore SDK计算生产派生密钥。用户无需手动维护派生密钥,当派生密钥过期后,Tablestore SDK将自动进行刷新。

  • 在示例2中,用户直接提供访问密钥(AccessKey)与派生密钥(v4SigningAccessKey)。派生密钥在第二天将自动过期,用户需要实现派生密钥的定时更新能力,否则将无法访问表格存储服务。

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临时访问凭证访问表格存储

以下示例代码使用V4签名初始化Tablestore Client,获取实例下的数据表列表并打印到控制台。

  • 在示例1中,用户仅需提供STS临时访问凭据,由Tablestore SDK计算生产派生密钥。用户无需手动维护派生密钥,当派生密钥过期后,Tablestore SDK将自动进行刷新。

  • 在示例2中,用户直接提供STS临时访问凭据与派生密钥(v4SigningAccessKey)。派生密钥在第二天将自动过期,用户需要实现派生密钥的定时更新能力,否则将无法访问表格存储服务。

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();
        }
    }
}
  • 本页导读 (1)
  • 背景信息
  • 请求流程
  • 示例代码