URL Signing
Sufy supports including a signature in the URL when downloading resources. The signature only needs to be calculated using the URL Signing Keys of buckets, without requiring the Access Keys of the account.
Both the service domains of MOS(Miku Object Storage) and the CDN domains of Sufy support downloading and accessing resources by using URL signature.
Examples:
https://examplebucket.mos.ap-southeast-2.sufybkt.com/exampleobject?expires=<expires>&token=<urlSigingKeyID>:<signature>
https://ndjsknjdskc.sufydely.com/exampleobject?expires=<expires>&token=<urlSigingKeyID>:<signature>
Parameters
- expires:Signature expiration time, Unix timestamp
- token:Authorization filed,constructed by concatenating the urlSigningKeyID and the encoded signature with a colon (":") ,token=
<urlSigingKeyID>:<signature>
- "token" must be at the end of the URL, and any parameters after "token" will be ignored. The user-defined query key is prohibited from using the two reserved fields "expires" and "token".
Signature calculation process
- Base URL for file
URL = 'https://ndjsknjdskc.sufydely.com/exampleobject?param=aaa/bb'
- Add the "expries" parameter (Unix timestamp) to the URL for the expiration time, and perform URLEncoding.
EncodingURL = 'https://ndjsknjdskc.sufydely.com/exampleobject?param=aaa%2Fbb&expries=1720627200'
- Calculate the HMAC-SHA1 signature on the EncodingURL string (assuming the secret key is
MY_URL_SIGNING_KEY
), and then perform URL-safe Base64 encoding on the result.
signature = urlsafe_base64_encode(hmac_sha1(EncodingURL, 'MY_URL_SIGNING_KEY'))='d_pZcYT7-uAd7z6D1es7vlyTF_s='
- Concatenate the urlSigningKeyID (assuming it is
MY_URL_SIGNING_KEY_ID
) with signature obtained in the previous step using the colon (:) character.
token = 'MY_URL_SUGNING_KEY_ID:d_pZcYT7-uAd7z6D1es7vlyTF_s='
- Append "token" to the EncodingURL obtained in step 2 to get the signed URL.
signedURL = 'https://ndjsknjdskc.sufydely.com/exampleobject?param=aaa%2Fbb&expries=1720627200&token=MY_URL_SUGNING_KEY_ID:d_pZcYT7-uAd7z6D1es7vlyTF_s='
Sample code for signature calculation
import (
"crypto/hmac"
"crypto/sha1"
"encoding/base64"
"fmt"
"io"
"io/ioutil"
"os"
"strings"
"time"
)
// The url must start with "https://" or "http://", and it cannot contain the "expires" or "token" query parameters.
func SignURL(url, keyID string, key string, expiration time.Time) string {
// Add the "expires" parameter to the URL
sep := "?"
if strings.Contains(url, "?") {
sep = "&"
}
url += sep
url += fmt.Sprintf("expires=%d", expiration.Unix())
// Calculate the HMAC-SHA1 signature
mac := hmac.New(sha1.New, []byte(key))
mac.Write([]byte(url))
sig := base64.URLEncoding.EncodeToString(mac.Sum(nil))
// Construct the token and append the token to the URL
url += fmt.Sprintf("&token=%s:%s", keyID, sig)
return url
}