In Object Storage Service (OSS), the Authorization header is the most common method that is used to provide authentication information. Except for POST requests and requests that are signed by using query parameters, all OSS operations use the Authorization header for authentication. This topic describes how to include a V4 signature in the Authorization header.
Use OSS SDKs to automatically sign requests
OSS SDKs support the automatic implementation of V4 signatures. Initiating requests by using OSS SDKs eliminates the need for manual signing. The following table provides initialization code samples and V4 signing implementations for different programming languages.
SDK | Client initialization | Signing implementation |
Java | ||
PHP | ||
Node.js | ||
Browser.js | ||
Python | ||
Go | ||
C++ | ||
C |
Calculation of the Authorization header
You may need to manually calculate a signature in some scenarios. For example, when you initiate API requests, you must calculate the Authorization header value. When you calculate the Authorization header value, separate the signature algorithm version and signature information in the Authorization
header with a space. The following table describes the components of the Authorization header.
Component | Description |
Signature algorithm | The algorithm that is used to calculate the signature. Valid value: OSS4-HMAC-SHA256. |
Signature information | The parameters used to calculate the signature. The signature information is in the form of key-value pairs. Separate key-value pairs with commas (,), and connect keys and values with equal signs (=). The keys in the signature information include two required fields (
|
Format
Authorization: "OSS4-HMAC-SHA256 Credential=" + AccessKeyId + "/" + SignDate + "/" + SignRegion + "/oss/aliyun_v4_request, " + [ "AdditionalHeaders=" + AdditionalHeadersVal + ", " ] + "Signature=" + SignatureVal
Example
Authorization: OSS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20231203/cn-hangzhou/oss/aliyun_v4_request, AdditionalHeaders=host;userdefine, Signature=4b663e424d2db9967401ff6ce1c86f8c83cabd77d9908475239d9110642c63fa
When you send a request by using the temporary access credentials obtained from Security Token Service (STS), you must add the security token to the request headers by specifying the x-oss-security-token:security-token
header. For more information about how to obtain a security token, see AssumeRole.
Signature calculation process
A signature calculation is a three-step process:
Step 1: Create a canonical request based on the required request elements, such as the HTTP method.
Step 2: Create a hash of the canonical request and concatenate the hash of the canonical request and the required elements such as OSS4-HMAC-SHA256 to create a string to sign.
Step 3: Use HMAC-SHA256 to create a signing key and then use HMAC-SHA256 to calculate the signature based on the signing key and the string to sign that you created in Step 2.
For more information about the required elements in each of the steps, refer to the following flowchart. For more information about signature calculation examples, see Signature calculation example.
Step 1: Create a canonical request
Step 2: Create a string to sign
Step 3: Calculate the signature
Signature calculation example
In this example, the PutObject operation is used to describe how to include a V4 signature in the Authorization header.
Parameters
Parameter
Example
AccessKeyId
accesskeyid
AccessKeySecret
accesskeysecret
Timestamp
20231203T121212Z
Bucket
examplebucket
Object
exampleobject
Region
cn-hangzhou
PutObject
PUT /exampleobject HTTP/1.1 Content-MD5: eB5eJF1ptWaXm4bijSPyxw Content-Type: text/html Date: Sun, 03 Dec 2023 12:12:12 GMT Host: examplebucket.oss-cn-hangzhou.aliyuncs.com Authorization: SignatureToBeCalculated x-oss-date: 20231203T121212Z x-oss-meta-author: alice x-oss-meta-magic: abracadabra x-oss-content-sha256: UNSIGNED-PAYLOAD
To include a V4 signature in the Authorization header, perform the following steps:
Create a canonical request.
PUT /examplebucket/exampleobject content-md5:eB5eJF1ptWaXm4bijSPyxw content-type:text/html host:examplebucket.oss-cn-hangzhou.aliyuncs.com x-oss-content-sha256:UNSIGNED-PAYLOAD x-oss-date:20231203T121212Z x-oss-meta-author:alice x-oss-meta-magic:abracadabra host UNSIGNED-PAYLOAD
Create a string to sign.
OSS4-HMAC-SHA256 20231203T121212Z 20231203/cn-hangzhou/oss/aliyun_v4_request 129b14df88496f434606e999e35dee010ea1cecfd3ddc378e5ed4989609c1db3
Calculate the signature.
Calculate the signing key.
HMAC-SHA256(HMAC-SHA256(HMAC-SHA256(HMAC-SHA256("aliyun_v4" + "accesskeysecret", "20231203"), "cn-hangzhou"), "oss"), "aliyun_v4_request");
Calculate the signature based on the following formula.
NoteSignature = HEX(HMAC-SHA256(Signingkey,StringToSign))
4b663e424d2db9967401ff6ce1c86f8c83cabd77d9908475239d9110642c63fa
Add the signature to the Authorization header.
OSS4-HMAC-SHA256 Credential=accesskeyid/20231203/cn-hangzhou/oss/aliyun_v4_request,AdditionalHeaders=host,Signature=4b663e424d2db9967401ff6ce1c86f8c83cabd77d9908475239d9110642c63fa
Sample code
import com.aliyun.oss.common.utils.BinaryUtil;
import org.apache.commons.codec.digest.DigestUtils;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
/**
* Signature Demo
*/
public class Demo1 {
/**
* Signature calculation
*
* @return Authorization
*/
public static void main(String[] args) throws Exception {
// Step 1: Construct a canonical request.
String canonicalRequest =
"PUT\n" +
"/examplebucket/exampleobject\n" +
"\n" +
"content-md5:eB5eJF1ptWaXm4bijSPyxw\n" +
"content-type:text/html\n" +
"host:examplebucket.oss-cn-hangzhou.aliyuncs.com\n" +
"x-oss-content-sha256:UNSIGNED-PAYLOAD\n" +
"x-oss-date:20231203T121212Z\n" +
"x-oss-meta-author:alice\n" +
"x-oss-meta-magic:abracadabra\n" +
"\n" +
"host\n" +
"UNSIGNED-PAYLOAD";
// Step 2: Create a string to sign.
String stringToSign = "OSS4-HMAC-SHA256\n" +
"20231203T121212Z\n" +
"20231203/cn-hangzhou/oss/aliyun_v4_request\n" +
DigestUtils.sha256Hex(canonicalRequest);
// Step 3: Calculate the signature.
// Set accesskeysecret to the AccessKey secret of the RAM user and date to the actual date, such as 20231203.
byte[] dateKey = hmacsha256(("aliyun_v4" + "accesskeysecret").getBytes(), "20231203");
// Specify the region in which the requested resource resides. Example: cn-hangzhou.
byte[] dateRegionKey = hmacsha256(dateKey, "cn-hangzhou");
byte[] dateRegionServiceKey = hmacsha256(dateRegionKey, "oss");
byte[] signingKey = hmacsha256(dateRegionServiceKey, "aliyun_v4_request");
byte[] result = hmacsha256(signingKey, stringToSign);
String signature = BinaryUtil.toHex(result);
System.out.println("signature:" + signature);
String authorization = "OSS4-HMAC-SHA256 " +
"Credential=accesskeyid/20231203/cn-hangzhou/oss/aliyun_v4_request," +
"AdditionalHeaders=host," +
"Signature=" + signature;
System.out.println("Authorization:" + authorization);
}
public static byte[] hmacsha256(byte[] key, String data) {
try {
// Initialize the HMAC key specification, set the algorithm to HMAC-SHA256, and use the provided key.
SecretKeySpec secretKeySpec = new SecretKeySpec(key, "HmacSHA256");
// Obtain a Mac instance and use the getInstance method to set the algorithm to HMAC-SHA256.
Mac mac = Mac.getInstance("HmacSHA256");
// Use the key to initialize the Mac instance.
mac.init(secretKeySpec);
// Calculate the HMAC value. Use the doFinal method to receive the data to be calculated and return the calculation results in arrays.
byte[] hmacBytes = mac.doFinal(data.getBytes());
return hmacBytes;
} catch (Exception e) {
throw new RuntimeException("Failed to calculate HMAC-SHA256", e);
}
}
}