AccessKey pair security
The V4 signature algorithm protects your AccessKey pair by using a short-lived derived key for authentication instead of the AccessKey secret directly. If the derived key is compromised, only resources in a specific region and service are affected, and the derived key is valid for no more than one day—the derived key expires automatically the next day.
How the V4 signature works
The V4 signature algorithm replaces direct use of the AccessKey secret with a derived key—a value computed from your AccessKey secret, the current date, the region, and the product code.
If you use V4 signatures and one of the signatures is stolen, other regions and services that belong to the Alibaba Cloud account or RAM user are not affected. The stolen V4 signature is valid for no more than one day. You can use V4 signatures to ensure the security of your AccessKey pair.
Scope: Only the specific region and service are affected, not your entire account.
-
Time: The derived key is valid for no more than one day and expires automatically the next day.
NoteYou can use V4 signatures and keep AccessKey pairs confidential to ensure the security of your AccessKey pairs. For example, you can store AccessKey pairs in environment variables in code.
Request flow
The client computes a derived key from the AccessKey pair using the V4 signature algorithm and sends the request with this derived key.
The server receives the request and verifies the derived key to authenticate the caller.
-
If authentication succeeds, the server processes the request and returns the result.
NoteIf authentication fails, the server denies access from the client.
The client receives the response.
Sample code
Tablestore SDK for Java V5.16.1 and later support the V4 signature algorithm. Before you use the V4 signature algorithm, make sure that the SDK version you use supports it.
Use an AccessKey pair for initialization
In this example, the AccessKey pair of an Alibaba Cloud account or RAM user is used to describe how to configure access credentials. For more information, see How do I obtain an AccessKey pair?
The following sample code initializes a Tablestore client using a V4 signature, lists the data tables in an instance, and prints the table names.
Example 1 (recommended): Provide your AccessKey pair. The SDK computes and refreshes the derived key automatically.
Example 2: Provide both the AccessKey pair and a pre-computed derived key (
v4 SigningAccessKey). The derived key expires the next day. You must implement a mechanism to refresh it before expiry, or requests to Tablestore will fail.
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) {
// Specify the region where the instance resides. Example: cn-hangzhou.
final String region = "yourRegion";
// Specify the instance name.
final String instanceName = "yourInstanceName";
// Specify the instance endpoint.
final String endpoint = "yourEndpoint";
// Obtain the AccessKey ID and AccessKey secret from environment variables.
final String accessKeyId = System.getenv("TABLESTORE_ACCESS_KEY_ID");
final String accessKeySecret = System.getenv("TABLESTORE_ACCESS_KEY_SECRET");
{
/**
* Example 1: Construct {@link DefaultCredentials} from the AccessKey ID and
* AccessKey secret, then generate {@link V4Credentials}.
*/
DefaultCredentials credentials = new DefaultCredentials(accessKeyId, accessKeySecret);
V4Credentials credentialsV4 = V4Credentials.createByServiceCredentials(credentials, region);
CredentialsProvider provider = new DefaultCredentialProvider(credentialsV4);
// Initialize the Tablestore client with V4Credentials.
SyncClient client = new SyncClient(endpoint, provider, instanceName, null, new ResourceManager(null, null));
// do something
client.listTable().getTableNames().forEach(System.out::println);
// Shut down the Tablestore client.
client.shutdown();
}
{
/**
* Example 2: Construct {@link V4Credentials} directly from the AccessKey pair
* and a pre-computed derived key.
*/
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
String signDate = dateFormat.format(new Date()); // Example: 20230527
String v4SigningAccessKey = CalculateV4SigningKeyUtil.finalSigningKeyString(accessKeySecret, signDate, region, PRODUCT, SIGNING_KEY_SIGN_METHOD); // Derived key
V4Credentials credentialsV4 = new V4Credentials(accessKeyId, v4SigningAccessKey, region, signDate);
CredentialsProvider provider = new DefaultCredentialProvider(credentialsV4);
// Initialize the Tablestore client with V4Credentials.
SyncClient client = new SyncClient(endpoint, provider, instanceName, null, new ResourceManager(null, null));
// do something
client.listTable().getTableNames().forEach(System.out::println);
// Shut down the Tablestore client.
client.shutdown();
}
}
}
Use STS for initialization
For information about how to obtain temporary access credentials from Security Token Service (STS), see Use temporary access credentials obtained from STS to access Tablestore .
The following sample code initializes a Tablestore client using a V4 signature with STS temporary access credentials, lists the data tables in an instance, and prints the table names.
Example 1 (recommended): Provide the temporary access credentials from STS. The SDK computes and refreshes the derived key automatically.
Example 2: Provide both the STS temporary access credentials and a pre-computed derived key (
v4 SigningAccessKey). The derived key expires the next day. You must implement a mechanism to refresh it before expiry, or requests to Tablestore will fail.
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) {
// Specify the region where the instance resides. Example: cn-hangzhou.
final String region = "yourRegion";
// Specify the instance name.
final String instanceName = "yourInstanceName";
// Specify the instance endpoint.
final String endpoint = "yourEndpoint";
// Obtain the temporary AccessKey ID, temporary AccessKey secret, and security token from environment variables.
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");
{
/**
* Example 1: Construct {@link DefaultCredentials} from the temporary AccessKey ID,
* AccessKey secret, and security token, then generate {@link V4Credentials}.
*/
DefaultCredentials credentials = new DefaultCredentials(accessKeyId, accessKeySecret, securityToken);
V4Credentials credentialsV4 = V4Credentials.createByServiceCredentials(credentials, region);
CredentialsProvider provider = new DefaultCredentialProvider(credentialsV4);
// Initialize the Tablestore client with V4Credentials.
SyncClient client = new SyncClient(endpoint, provider, instanceName, null, new ResourceManager(null, null));
// do something
client.listTable().getTableNames().forEach(System.out::println);
// Shut down the Tablestore client.
client.shutdown();
}
{
/**
* Example 2: Construct {@link V4Credentials} directly from the STS temporary
* access credentials and a pre-computed derived key.
*/
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
String signDate = dateFormat.format(new Date()); // Example: 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);
// Initialize the Tablestore client with V4Credentials.
SyncClient client = new SyncClient(endpoint, provider, instanceName, null, new ResourceManager(null, null));
// do something
client.listTable().getTableNames().forEach(System.out::println);
// Shut down the Tablestore client.
client.shutdown();
}
}
}