You can include the Authorization header in an HTTP request to carry signature information and indicate that the requester is authorized.

Sign requests when you use OSS SDKs

Requests initiated by using Object Storage Service (OSS) SDKs are automatically signed. You do not need to manually add signatures to requests. For more information about how requests are signed when you use OSS SDKs for different programming languages, see the sample code of OSS SDKs. The following table describes the sample code used to sign requests initiated by using OSS SDKs for different programming languages.
SDK Sample code
Java SDK
Python SDK
.Net SDK OssRequestSigner.cs
PHP SDK OssClient.php
C SDK oss_auth.c
JavaScript SDK client.js
Go SDK auth.go
Ruby SDK util.rb
iOS SDK OSSModel.m
Android SDK

Calculation of the Authorization header

  • Calculation method
    Authorization = "OSS " + AccessKeyId + ":" + Signature
    Signature = base64(hmac-sha1(AccessKeySecret,
                VERB + "\n"
                + Content-MD5 + "\n" 
                + Content-Type + "\n" 
                + Date + "\n" 
                + CanonicalizedOSSHeaders
                + CanonicalizedResource))
  • Parameters
    Parameter Required Example Description
    AccessKeySecret Yes OtxrzxIsfpFjA7Sw******8Bw21TLhquhboDYROV The AccessKey secret that is used to sign the request.
    VERB Yes PUT The method of the HTTP request, such as PUT, GET, POST, HEAD, or DELETE.
    \n No \n A line feed.
    Content-MD5 No eB5eJF1ptWaXm4bijSPyxw== The Content-MD5 is the MD5 hash of requested content. The message content that excludes the header is calculated to obtain an MD5 hash, which is a 128-bit number. This number is encoded with Base64 into a Content-MD5 value. For more information, visit RFC 2616 Content-MD5.

    Optional. This request header can be used to check the message validity. The message content is valid if the received message content is the same as the content that is sent.

    For more information about how to calculate the value of Content-MD5, see Calculation of Content-MD5.

    Content-Type No application/octet-stream Optional. The type of the request content.
    Date Yes Sun, 22 Nov 2015 08:16:38 GMT Required. The time when this operation is performed. The value of this parameter must be in GMT.
    Notice If the difference between the time specified by the Date header in a request and the time on the server when the request is received is greater than 15 minutes, OSS rejects the request and returns HTTP status code 403.
    CanonicalizedOSSHeaders No x-oss-meta-a:a\nx-oss-meta-b:b\nx-oss-meta-c:c\n Optional. The HTTP headers that are prefixed with x-oss-. The HTTP headers are sorted in alphabetical order.
    • CanonicalizedOSSHeaders can be left empty. In this case, the \n delimiter at the end can be removed.
    • If CanonicalizedOSSHeaders includes only one header, the \n delimiter must be added at the end of the header. Example: x-oss-meta-a\n.
    • If CanonicalizedOSSHeaders includes multiple headers, you must add the \n delimiter to each header. Example: x-oss-meta-a:a\nx-oss-meta-b:b\nx-oss-meta-c:c\n.

    For more information about how to construct CanonicalizedOSSHeaders, see Creation of CanonicalizedOSSHeaders.

    CanonicalizedResource Yes /examplebucket/ Required. The OSS resource you want to access.

    For more information about how to construct CanonicalizedResource, see Creation of CanonicalizedResource.

  • Signature examples
    Request Formula Signature string
    PUT /nelson HTTP/1.0 Content-MD5: eB5eJF1ptWaXm4bijSPyxw== Content-Type: text/html Date: Thu, 17 Nov 2005 18:49:58 GMT Host: x-oss-meta-author: x-oss-meta-magic: abracadabra Signature = base64(hmac-sha1(AccessKeySecret,VERB + "\n" + Content-MD5 + "\n"+ Content-Type + "\n" + Date + "\n" + CanonicalizedOSSHeaders+ CanonicalizedResource)) “PUT\n eB5eJF1ptWaXm4bijSPyxw==\n text/html\n Thu, 17 Nov 2005 18:49:58 GMT\n x-oss-meta-magic:abracadabra\\n/oss-example/nelson

    If AccessKey ID is set to "44CF959******252F707" and AccessKey Secret is set to "OtxrzxIsfpFjA7Sw******8Bw21TLhquhboDYROV", you can run the following Python code to calculate the signature:

    import hmac
    import hashlib
    h ="OtxrzxIsfpFjA7Sw******8Bw21TLhquhboDYROV"),
                 oss2.to_bytes("PUT\nODBGOERFMDMzQTczRUY3NUE3NzA5QzdFNUYzMDQxNEM=\ntext/html\nThu, 17 Nov 2005 18:49:58 GMT\nx-oss-meta-magic:abracadabra\\n/oss-example/nelson"), hashlib.sha1)
    signature = oss2.utils.b64encode_as_string(h.digest())
    print("Signature: %s" % signature)

    The calculated signature is 26NBxoKd******Dv6inkoDft/yA=. Therefore, the value of the Authorization header is OSS 44CF95900***BF252F707:26NBxoKd******Dv6inkoDft/yA=, which is in the following format: "OSS"+ AccessKey ID + ":" + Signature. The following example shows the final request that includes the Authorization header:

    PUT /nelson HTTP/1.0
    Authorization:OSS 44CF95900***BF252F707:26NBxoKd******Dv6inkoDft/yA=
    Content-Md5: eB5eJF1ptWaXm4bijSPyxw==
    Content-Type: text/html
    Date: Thu, 17 Nov 2005 18:49:58 GMT
    x-oss-meta-magic: abracadabra

Detail analysis:

  • If the imported AccessKey ID does not exist or is not activated, 403 Forbidden and InvalidAccessKeyId are returned. If the imported AccessKey ID is activated but OSS determines that a signature error occurs in the request, 403 Forbidden is returned with the correct signature string in the response to verify the encryption. You can check whether the signature string is correct based on the response.
    Sample response
    <?xml version="1.0" ?>
         The request signature we calculated does not match the signature you provided. Check your key and signing method.
         47 45 54 0a 0a 0a 57 65 64 2c 20 31 31 20 4d 61 79 20 32 30 31 31 20 30 37 3a 35 39 3a 32 35 20 47 4d 54 0a 2f 75 73 72 65 61 6c 74 65 73 74 3f 61 63 6c
    Wed, 11 May 2011 07:59:25 GMT
  • If the format of the Authorization value in the request is invalid, 400 Bad Request and InvalidArgument are returned.
  • The date and time specified in all OSS requests must be in GMT defined in HTTP/1.1, in which date is in the following format:
    date1 = 2DIGIT SP month SP 4DIGIT; day month year (e.g., 02 Jun 1982)
    Note In the preceding date format, "day" uses two digits. Therefore, "Jun 2", "2 Jun 1982", and "2-Jun-1982" are all invalid date formats.
    • If the Date header is not specified or is in an invalid format in a signed request, 403 Forbidden is returned with AccessDenied.
    • If the difference between the time specified by the Date header in a request and the time on the server when the request is received is greater than 15 minutes, 403 Forbidden and RequestTimeTooSkewed are returned.

Creation of CanonicalizedOSSHeaders

All HTTP headers prefixed with x-oss- are called CanonicalizedOSSHeaders. You can perform the following steps to create CanonicalizedOSSHeaders:

  1. Convert the names of all HTTP request headers prefixed with x-oss- into lowercase letters. For example, convert X-OSS-Meta-Name: TaoBao into x-oss-meta-name: TaoBao.
  2. If the request is sent by using an access credential obtained from STS, you must add the obtained security-token value to the signature string in the x-oss-security-token:security-token format.
    Note For more information about how to configure Security Token Service (STS), see Use a temporary credential provided by STS to access OSS in OSS Developer Guide. You can call the AssumeRole operation or use STS SDKs for various programming languages to obtain a temporary access credential. For more information, see STS SDK overview. The temporary access credential contains a security token and a temporary AccessKey pair. The AccessKey pair consists of an AccessKey ID and an AccessKey secret.
  3. Sort all HTTP request headers that are converted in Step 1 in alphabetical order.
  4. Delete all spaces on each side of the delimiter between each header and value. For example, convert x-oss-meta-name: TaoBao into x-oss-meta-name:TaoBao.
  5. Separate all headers with the \n delimiter to create CanonicalizedOSSHeaders.

Creation of CanonicalizedResource

The OSS resources that you send requests to access are called CanonicalizedResource. You can perform the following operations to create CanonicalizedResource:

  1. Set CanonicalizedResource to an empty string "".
  2. Specify the OSS resource you want to access in the following format: /BucketName/ObjectName.
    • If the resource you want to access is a bucket instead of an object, set CanonicalizedResource to "/BucketName/".
    • If the resource you want to access is not a bucket or an object, set CanonicalizedResource to "/".
    • If the resource that you want to access contains subresources, sort all subresources in alphabetical order and separate them with the ampersand (& ) delimiter. Add a question mark (?) and the subresource string to the end of the CanonicalizedResource string. In this example, the created CanonicalizedResource is in the following format: /BucketName/ObjectName?acl&uploadId=UploadId.

      OSS supports the following subresources: acl, uploads, location, cors, logging, website, referer, lifecycle, delete, append, tagging, objectMeta, uploadId, partNumber, security-token, position, img, style, styleName, replication, replicationProgress, replicationLocation, cname, bucketInfo, comp, qos, live, status, vod, startTime, endTime, symlink, x-oss-process, response-content-type, response-content-language, response-expires, response-cache-control, response-content-disposition, and response-content-encoding.

      You can specify the following three types of subresources:
      • Resource identifiers such as acl, append, uploadId, and symlink subresources For more information, see Bucket operations and Object operations.
      • Subresources that specify the response header fields. Example: response-***. For more information, see Request Parameters in GetObject.
      • Object processing methods such as x-oss-process. For more information, see IMG.

Calculation of the signature

  • The signature string used to calculate the signature must be UTF-8-encoded. A signature string that contains Chinese characters must be encoded in UTF-8. The encoded signature string is used together with AccessKeySecret to calculate the final signature.
  • The HMAC-SHA1 method defined in RFC 2104 is used to calculate the signature. In this method, Key indicates AccessKeySecret.
  • Content-Type and Content-MD5 can be left unspecified in a request. However, if OSS needs to verify the signature of the request, the values of these two headers must be replaced by line feeds (\n).
  • Non-standard HTTP headers prefixed with x-oss- must be added to the signature string. Other non-standard HTTP headers are ignored by OSS. For example, the x-oss-magic header in the following example must be included in the signature string.
    Note Headers prefixed with x-oss- in the signature string must comply with the following conventions:
    • The names of headers must be in lowercase.
    • The headers must be sorted in alphabetical order.
    • No space exists before or after the colon (:) that separates each header name and value.
    • Each header is followed by a line feed (\n). If no header is specified, CanonicalizedOSSHeaders is empty.

Calculation of Content-MD5

The following examples use a string "123456789" to show how to calculate the Content-MD5 value of the request content:

  • Correct calculation
    1. Calculate the MD5 hash of the string, which is a 128-bit binary array.
    2. Encode the binary array (instead of the 32-bit string) in Base64.
    The following Python code provides an example on how to calculate the Content-MD5 value:
    >>> import base64,hashlib
    >>> hash = hashlib.md5()
    >>> hash.update("0123456789")   // If you use Python 3, change the code to hash.update(b"0123456789"). 
    >>> base64.b64encode(hash.digest())

    Call hash.digest() to calculate the 128-bit binary array.

    >>> hash.digest()
  • Incorrect calculation
    Note A common incorrect operation is to encode the calculated 32-bit string in Base64 to obtain the Content-MD5 value.
    # Call hash.hexdigest() to obtain a 32-bit plaintext string. 
    >>> hash.hexdigest()
    # The following code provides an example on encoding the incorrect MD5 hash in Base64: 
    >>> base64.b64encode(hash.hexdigest())