All Products
Search
Document Center

Object Storage Service:(Recommended) Include a V4 signature in the Authorization header

Last Updated:Aug 08, 2024

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

Initialization

OSSV4Signer.java

PHP

Initialization

SignerV4.php

Node.js

Initialization

client.js

Browser.js

Initialization

Python

Initialization

auth.py

Go

Initialization

v4.go

C++

Initialization

SignerV4.cc

C

Initialization

oss_auth.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 (Credential and Signature) and one optional field (AdditionalHeaders).

  • Credential: the AccessKey ID and the scope information, which are separated by forward slashes (/).

  • Signature: the calculated signature.

  • AdditionalHeaders: optional request headers that are used to calculate the signature. If you specify multiple headers, separate them with semicolons (;). Header keys are not case-sensitive and must be sorted lexicographically.

  • 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
Note

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.

image

Step 1: Create a canonical request

Concatenate the required elements in the canonical request format that OSS uses to calculate a signature.

Canonical request format

HTTP Verb + "\n" +
Canonical URI + "\n" +
Canonical Query String + "\n" +
Canonical Headers + "\n" +
Additional Headers + "\n" +
Hashed PayLoad

The following table describes the preceding parameters.

Note

For more information about the following technical terms, refer to the HTTP protocol.

Parameter

Type

Required

Example

Description

HTTP Verb

Enumeration

Yes

PUT

The HTTP method, which can be PUT, GET, POST, HEAD, DELETE, or OPTIONS.

Canonical URI

String

Yes

/examplebucket/exampleobject

The URI-encoded string. Do not encode the forward slash (/) in the URI.

  • The URI starts with a forward slash (/) that follows the domain name up to the end of the string if query string parameters are not included.

  • The URI starts with a forward slash (/) that follows the domain name and ends with a question mark (?) if query string parameters are included.

The following items describe how to specify a canonical URI based on the resources included in the request URI:

Note

The canonical URI must contain the description of the bucket. In most cases, the bucket description is included in the domain name.

  • If the request URI contains both a bucket name and an object name, the canonical URI is in the following format:

    /examplebucket/exampleobject.

  • If the request URI contains only a bucket name, the canonical URI is in the following format: /examplebucket/.

  • If the request URI does not contain a bucket name or an object name, the canonical URI is /.

Canonical Query String

String

Yes

UrlEncode("marker") + "=" + UrlEncode("someMarker") + "&" + UrlEncode("max-keys") + "=" + UrlEncode("20") + "&" + UrlEncode("prefix") + "=" + UrlEncode("somePrefix")

The URI-encoded query string parameters. You must URI-encode each key and value individually.

  • You must sort the parameters in the canonical query string in alphabetical order by key name. The sorting occurs after encoding. If multiple parameters have the same key, arrange the parameters in its original order and separate individual parameters with the ampersand (&).

  • If a key does not have a value, add only the key.

  • If a request does not include a query string, set the canonical query string to an empty string (""). You must add a line feed at the end.

Canonical Headers

String

Yes

host:cname.com

x-oss-content-sha256:UNSIGNED-PARYLOAD

x-oss-date:20231203T121212Z

A list of request headers with values.

  • A header key and value are separated by a colon (:), and headers are separated by a line feed.

  • Header keys must be in lowercase and sorted in alphabetical order. Leading or trailing spaces in header values must be trimmed.

  • Header keys are sorted in alphabetical order.

  • The value of the x-oss-date header must be in the ISO 8601 standard (example: 20231203T121212Z).

Canonical Headers are divided into two types:

  • Headers that must exist and are used for signature calculation:

    • x-oss-content-sha256 (Valid value: UNSIGNED-PARYLOAD)

    • The headers specified by Additional Headers and used for signature calculation

  • Headers that must be added to Canonical Headers if they are in the request:

    • Content-Type

    • Content-MD5

    • x-oss-*

Additional Headers

String

Yes

content-length;host

The headers to be added to calculate the signature, except for the Content-Type, Content-MD5, and x-oss-* headers. All header keys must be in lowercase and sorted in alphabetical order.

Hashed PayLoad

String

Yes

UNSIGNED-PAYLOAD

Valid value: UNSIGNED-PAYLOAD.

Example

"GET" | "PUT" | ... + "\n" +
UrlEncode(<Resource>) + "\n" +
UrlEncode(<QueryParam1>) + "=" + UrlEncode(<Value>) + "&" + UrlEncode(<QueryParam2>) + "\n" +
Lowercase(<HeaderName1>) + ":" + Trim(<value>) + "\n" + Lowercase(<HeaderName2>) + ":" + Trim(<value>) + "\n" + 
Lowercase(<AdditionalHeaderName1>) + ";" + Lowercase(<AdditionalHeaderName2>) + "\n" +
UNSIGNED-PAYLOAD

Step 2: Create a string to sign

Create a hash of the canonical request and concatenate the hash and the other elements to create a string to sign.

  • Format

    "OSS4-HMAC-SHA256" + "\n" +
    TimeStamp + "\n" +
    Scope + "\n" +
    Hex(SHA256Hash(<CanonicalRequest>))

    The following table describes the preceding parameters.

    Parameter

    Type

    Required

    Example

    Description

    OSS4-HMAC-SHA256

    Enumeration

    Yes

    OSS4-HMAC-SHA25

    The algorithm used to create the hash of the canonical request. Set the value to OSS4-HMAC-SHA256.

    TimeStamp

    String

    Yes

    20231203T121212Z

    The current time in UTC. The time must follow the ISO 8601 standard.

    Scope

    String

    Yes

    20231203/cn-hangzhou/oss/aliyun_v4_request

    The scope information. This restricts the calculated signature to the specified region and service. Format:

    <SigningDate>/<SigningRegion>/oss/aliyun_v4_request
    • SigningDate: the date when the request is initiated.

    • SigningRegion: the region in which the requested resource resides.

    • oss: the name of the requested service. Valid value: oss.

    • aliyun_v4_request: the description of the signature version in the request. Set the value to aliyun_v4_request.

    CanonicalRequest

    String

    Yes

    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

    The string created in Step 1.

  • Example

    "OSS4-HMAC-SHA256" + "\n" +
    FormatISO8601 + "\n" +
    20231203/cn-hangzhou/oss/aliyun_v4_request + "\n" +
    Hex(SHA256Hash(<CanonicalRequest>))

Step 3: Calculate the signature

Create a signing key and use the signing key to calculate the signature.

  1. Use HMAC-SHA256 to create a signing key by using the following format.

    Note

    Two parameters are required when you use HMAC-SHA256 to create a signing key: KEY and MESSAGE.

    In the following code, SK is your AccessKey pair, Date is the current time in the ISO8601 format (example: 20231203), and region is the region in which the requested resource resides.

    DateKey = HMAC-SHA256("aliyun_v4" + SK, Date);
    DateRegionKey = HMAC-SHA256(DateKey, Region);
    DateRegionServiceKey = HMAC-SHA256(DateRegionKey, "oss");
    SigningKey = HMAC-SHA256(DateRegionServiceKey, "aliyun_v4_request");

    You can combine the preceding lines into only one line.

    SigningKey = HMAC-SHA256(HMAC-SHA256(HMAC-SHA256(HMAC-SHA256("aliyun_v4" + SK, Date), Region), "oss"), "aliyun_v4_request");
  2. Calculate the signature by using the signing key and string to sign.

    Signature = HEX(HMAC-SHA256(SigningKey, StringToSign))

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:

    1. 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
    2. Create a string to sign.

      OSS4-HMAC-SHA256
      20231203T121212Z
      20231203/cn-hangzhou/oss/aliyun_v4_request
      129b14df88496f434606e999e35dee010ea1cecfd3ddc378e5ed4989609c1db3
    3. Calculate the signature.

      1. Calculate the signing key.

        HMAC-SHA256(HMAC-SHA256(HMAC-SHA256(HMAC-SHA256("aliyun_v4" + "accesskeysecret", "20231203"), "cn-hangzhou"), "oss"), "aliyun_v4_request");
      2. Calculate the signature based on the following formula.

        Note

        Signature = HEX(HMAC-SHA256(Signingkey,StringToSign))

        4b663e424d2db9967401ff6ce1c86f8c83cabd77d9908475239d9110642c63fa
    4. 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);
        }
    }
}