Note:
- This document is only for the COS XML version.
- It does not apply to
POST Object
requests over HTTP.
RESTful APIs support anonymous and signed HTTP requests, which help you use COS resources. For a signed request, the COS server will authenticate its initiator.
The COS server performs HMAC (Hash Message Authentication Code) authentication schema.
Besides, pre-signed URLs are provided in all language-specific SDKs so that you can easily access signed URLs and process requests. For more information, please see Pre-signed URL in applicable language-specific SDK documentation.
In use cases where COS objects need to be published to the public, public read/private write is usually configured. It means that every one can read, but only accounts you specify with ACL policies can write to your objects. In this case, you can use ACL policies together with API request signature to authenticate access and control operation permission and period.
Note:
The API request signature described in this document is already included in the SDK. You need to follow the steps below only if you want to redevelop based on the initial APIs.
In this case, multiple layers of security protection can be included for API requests:
APPID
, SecretId
, and SecretKey
.HMAC-SHA1
, SHA1
, and UrlEncode
functions for the chosen language.HMAC-SHA1
and SHA1
functions input UTF-8 encoded strings and output lowercase hexadecimal strings. The UrlEncode
function works based on UTF-8 encoding. The following printable special characters in the ASCII range should also be encoded:Character | Decimal | Hex | Character | Decimal | Hex |
---|---|---|---|---|---|
(Space) | 32 | 20 | ; | 59 | 3B |
! | 33 | 21 | < | 60 | 3C |
" | 34 | 22 | = | 61 | 3D |
# | 35 | 23 | > | 62 | 3E |
$ | 36 | 24 | ? | 63 | 3F |
% | 37 | 25 | @ | 64 | 40 |
& | 38 | 26 | [ | 91 | 5B |
' | 39 | 27 | \ | 92 | 5C |
( | 40 | 28 | ] | 93 | 5D |
) | 41 | 29 | ^ | 94 | 5E |
* | 42 | 2A | ` | 96 | 60 |
+ | 43 | 2B | { | 123 | 7B |
, | 44 | 2C | | | 124 | 7C |
/ | 47 | 2F | } | 125 | 7D |
: | 58 | 3A |
StartTimestamp
for the current time, which is the total number of seconds starting from January 1, 1970, 00:00:00 UTC (January 1, 1970, 08:00:00 Beijing time).EndTimestamp
for the moment the signature will expire based on the timestamp above and the expected valid duration of the signature.KeyTime
) by splicing the two timestamps above in the format of StartTimestamp;EndTimestamp
, such as 1557902800;1557910000
.Calculate the message digest (hash value in hexadecimal lowercase) by using HMAC-SHA1 with SecretKey as the key and KeyTime as the message, which is SignKey
, such as eb2519b498b02ac213cb1f3d1a3d27a3b3c9bc5f
.
Map
and key list KeyList
:value
, the value
is considered to be an empty string. For example, the request path /?acl
is considered as /?acl=
.Note:
The parameters in an HTTP request are what comes after
?
in the request path. For example, in the request path/?versions&prefix=example-folder%2F&delimiter=%2F&max-keys=10
, the request parameters areversions&prefix=example-folder%2F&delimiter=%2F&max-keys=10
.
KeyList
in lexicographical order.Map
in the order of the KeyList
in the format of key1=value1&key2=value2&key3=value3
, which is the HttpParameters
.KeyList
in the format of key1;key2;key3
, which is the UrlParamList
./?prefix=example-folder%2F&delimiter=%2F&max-keys=10
delimiter;max-keys;prefix
delimiter=%2F&max-keys=10&prefix=example-folder%2F
Note:
The request parameters in the request path are URL-encoded too when the request is actually sent; therefore, be careful not to repeat the URL-encoding.
/exampleobject?acl
acl
acl=
Map
and the key list KeyList
, where keys are URL-encoded and converted to lowercase and values are URL-encoded.KeyList
in lexicographical order.Map
in the order of the KeyList
in the format of key1=value1&key2=value2&key3=value3
, which is the HttpHeaders
.KeyList
in the format of key1;key2;key3
, which is the HeaderList
.Request headers:
Host: examplebucket-1250000000.cos.ap-shanghai.myqcloud.com
Date: Thu, 16 May 2019 03:15:06 GMT
x-cos-acl: private
x-cos-grant-read: uin="100000000011"
Calculate and get:
date;host;x-cos-acl;x-cos-grant-read
date=Thu%2C%2016%20May%202019%2003%3A15%3A06%20GMT&host=examplebucket-1250000000.cos.ap-shanghai.myqcloud.com&x-cos-acl=private&x-cos-grant-read=uin%3D%22100000000011%22
Generate the HttpString
based on the HTTP method, HTTP request path, HttpParameters, and HttpHeaders in the format of HttpMethod\nUriPathname\nHttpParameters\nHttpHeaders\n
.
Here:
HttpMethod
is converted to lowercase, such as get
or put
.UriPathname
is the request path, such as /
or /exampleobject
.\n
is a line break. The two line breaks (if any) bookending an empty string should be retained, such as in get\n/exampleobject\n\n\n
.Generate the StringToSign
based on the KeyTime and HttpString in the format of sha1\nKeyTime\nSHA1(HttpString)\n
.
Here:
sha1
is a fixed string.\n
is a line break.SHA1(HttpString)
is the message digest generated by calculating the HttpString with SHA1, which is in hexadecimal lowercase, such as 54ecfe22f59d3514fdc764b87a32d8133ea611e6
.Calculate the message digest by using HMAC-SHA1 with SignKey (in string form instead of original binary form) as the key and StringToSign as the message, which is Signature
, such as 01681b8c9d798a678e43b685a9f1bba0f6c0e012
.
Generate the actual signature based on SecretId, KeyTime, HeaderList, UrlParamList, and Signature in the following format:
q-sign-algorithm=sha1
&q-ak=SecretId
&q-sign-time=KeyTime
&q-key-time=KeyTime
&q-header-list=HeaderList
&q-url-param-list=UrlParamList
&q-signature=Signature
Note:
Line breaks in the sample above are for easy understanding only and are not included in a real signature.
Signed HTTP requests initiated to COS through RESTful APIs can pass the signature in the following ways:
Authorization: q-sign-algorithm=sha1&q-ak=...&q-sign-time=1557989753;1557996953&...&q-signature=...
/exampleobject?q-sign-algorithm=sha1&q-ak=...&q-sign-time=1557989753%3B1557996953&...&q-signature=...
Note:
In the sample above,
...
is used to substitute the specific signing information.
If temporary security credentials are used when the signature is calculated, then the security token field x-cos-security-token
should also be passed in when the request is sent. The method to pass in this field varies by how the signature is used:
x-cos-security-token
request header at the same time, such as:Authorization: q-sign-algorithm=sha1&q-ak=...&q-sign-time=1557989753;1557996953&...&q-signature=...
x-cos-security-token: ...
x-cos-security-token
request parameter at the same time, such as:/exampleobject?q-sign-algorithm=sha1&q-ak=...&q-sign-time=1557989753%3B1557996953&...&q-signature=...&x-cos-security-token=...
Note:
In the example above,
...
is used to substitute the specific signature and security token content.
KeyTime = [Now];[Expires]
SignKey = HMAC-SHA1([SecretKey], KeyTime)
HttpString = [HttpMethod]\n[HttpURI]\n[HttpParameters]\n[HttpHeaders]\n
StringToSign = sha1\nKeyTime\nSHA1(HttpString)\n
Signature = HMAC-SHA1(SignKey, StringToSign)
The samples below illustrate how to call HMAC-SHA1 in different languages:
$sha1HttpString = sha1('ExampleHttpString');
$signKey = hash_hmac('sha1', 'ExampleKeyTime', 'YourSecretKey');
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.codec.digest.HmacUtils;
String sha1HttpString = DigestUtils.sha1Hex("ExampleHttpString");
String signKey = HmacUtils.hmacSha1Hex("YourSecretKey", "ExampleKeyTime");
import hmac
import hashlib
sha1_http_string = hashlib.sha1('ExampleHttpString'.encode('utf-8')).hexdigest()
sign_key = hmac.new('YourSecretKey'.encode('utf-8'), 'ExampleKeyTime'.encode('utf-8'), hashlib.sha1).hexdigest()
var crypto = require('crypto');
var sha1HttpString = crypto.createHash('sha1').update('ExampleHttpString').digest('hex');
var signKey = crypto.createHmac('sha1', 'YourSecretKey').update('ExampleKeyTime').digest('hex');
import (
"crypto/hmac"
"crypto/sha1"
)
h := sha1.New()
h.Write([]byte("ExampleHttpString"))
sha1HttpString := h.Sum(nil)
var hashFunc = sha1.New
h = hmac.New(hashFunc, []byte("YourSecretKey"))
h.Write([]byte("ExampleKeyTime"))
signKey := h.Sum(nil)
Log in to the API Key Management page in the CAM Console to get your APPID
, SecretId
, and SecretKey
. Below is an example:
APPID | SecretId | SecretKey |
---|---|---|
1250000000 | AKIDQjz3ltompVjBni5LitkWHFlFpwkn9U5q | BQYIM75p8x0iWVFSIgqEKwFprpRSVHlz |
PUT /exampleobject(%E8%85%BE%E8%AE%AF%E4%BA%91) HTTP/1.1
Date: Thu, 16 May 2019 06:45:51 GMT
Host: examplebucket-1250000000.cos.ap-beijing.myqcloud.com
Content-Type: text/plain
Content-Length: 13
Content-MD5: mQ/fVh815F3k6TAUm8m0eg==
x-cos-acl: private
x-cos-grant-read: uin="100000000011"
ObjectContent
1557989151;1557996351
eb2519b498b02ac213cb1f3d1a3d27a3b3c9bc5f
(empty string)
(empty string)
content-length;content-md5;content-type;date;host;x-cos-acl;x-cos-grant-read
content-length=13&content-md5=mQ%2FfVh815F3k6TAUm8m0eg%3D%3D&content-type=text%2Fplain&date=Thu%2C%2016%20May%202019%2006%3A45%3A51%20GMT&host=examplebucket-1250000000.cos.ap-beijing.myqcloud.com&x-cos-acl=private&x-cos-grant-read=uin%3D%22100000000011%22
put\n/exampleobject(tencentcloud)\n\ncontent-length=13&content-md5=mQ%2FfVh815F3k6TAUm8m0eg%3D%3D&content-type=text%2Fplain&date=Thu%2C%2016%20May%202019%2006%3A45%3A51%20GMT&host=examplebucket-1250000000.cos.ap-beijing.myqcloud.com&x-cos-acl=private&x-cos-grant-read=uin%3D%22100000000011%22\n
sha1\n1557989151;1557996351\n8b2751e77f43a0995d6e9eb9477f4b685cca4172\n
3b8851a11a569213c17ba8fa7dcf2abec6935172
Here, (empty string) represents an empty string with a length of 0 and \n
a line break.
PUT /exampleobject(%E8%85%BE%E8%AE%AF%E4%BA%91) HTTP/1.1
Date: Thu, 16 May 2019 06:45:51 GMT
Host: examplebucket-1250000000.cos.ap-beijing.myqcloud.com
Content-Type: text/plain
Content-Length: 13
Content-MD5: mQ/fVh815F3k6TAUm8m0eg==
x-cos-acl: private
x-cos-grant-read: uin="100000000011"
Authorization: q-sign-algorithm=sha1&q-ak=AKIDQjz3ltompVjBni5LitkWHFlFpwkn9U5q&q-sign-time=1557989151;1557996351&q-key-time=1557989151;1557996351&q-header-list=content-length;content-md5;content-type;date;host;x-cos-acl;x-cos-grant-read&q-url-param-list=&q-signature=3b8851a11a569213c17ba8fa7dcf2abec6935172
ObjectContent
GET /exampleobject(%E8%85%BE%E8%AE%AF%E4%BA%91)?response-content-type=application%2Foctet-stream&response-cache-control=max-age%3D600 HTTP/1.1
Date: Thu, 16 May 2019 06:55:53 GMT
Host: examplebucket-1250000000.cos.ap-beijing.myqcloud.com
1557989753;1557996953
937914bf490e9e8c189836aad2052e4feeb35eaf
response-cache-control;response-content-type
response-cache-control=max-age%3D600&response-content-type=application%2Foctet-stream
date;host
date=Thu%2C%2016%20May%202019%2006%3A55%3A53%20GMT&host=examplebucket-1250000000.cos.ap-beijing.myqcloud.com
get\n/exampleobject(tencentcloud)\nresponse-cache-control=max-age%3D600&response-content-type=application%2Foctet-stream\ndate=Thu%2C%2016%20May%202019%2006%3A55%3A53%20GMT&host=examplebucket-1250000000.cos.ap-beijing.myqcloud.com\n
sha1\n1557989753;1557996953\n54ecfe22f59d3514fdc764b87a32d8133ea611e6\n
01681b8c9d798a678e43b685a9f1bba0f6c0e012
Here, \n
represents a line break.
GET /exampleobject(%E8%85%BE%E8%AE%AF%E4%BA%91)?response-content-type=application%2Foctet-stream&response-cache-control=max-age%3D600 HTTP/1.1
Date: Thu, 16 May 2019 06:55:53 GMT
Host: examplebucket-1250000000.cos.ap-beijing.myqcloud.com
Authorization: q-sign-algorithm=sha1&q-ak=AKIDQjz3ltompVjBni5LitkWHFlFpwkn9U5q&q-sign-time=1557989753;1557996953&q-key-time=1557989753;1557996953&q-header-list=date;host&q-url-param-list=response-cache-control;response-content-type&q-signature=01681b8c9d798a678e43b685a9f1bba0f6c0e012
Was this page helpful?