すべてのプロダクト
Search
ドキュメントセンター

Object Storage Service:URLにV4署名を含める (推奨)

最終更新日:Dec 23, 2024

URLを使用してリクエストを表現する場合は、HTTP Authorizationヘッダーを使用して認証情報を提供するだけでなく、クエリ文字列パラメーターを使用してリクエストを認証できます。 これにより、アクセス資格情報を公開することなく、特定のObject Storage Service (OSS) リソースに対する一時的なアクセス許可をユーザーに付与できます。 このトピックでは、URLにV4署名を含める方法について説明します。

OSS SDKを使用したV4シグネチャの自動実装

OSS SDKはV4シグネチャの自動実装をサポートしています。 OSS SDKを使用してリクエストを開始することを推奨します。 これにより、署名を手動で計算する必要がなくなります。 異なるプログラミング言語でOSS SDKを使用する場合にV4署名アルゴリズムを使用してリクエストに署名する方法の詳細については、OSS SDKのサンプルコードをご参照ください。 次の表に、さまざまなプログラミング言語でOSS SDKを使用する場合に、V4署名アルゴリズムを使用してリクエストに署名するために使用されるサンプルコードへの参照を示します。

SDK

サンプルコード

Java

OSSClientインスタンスの設定

OSSV4Signer.java

PHP

OSSClientインスタンスの設定

SignerV4.php

Node.js

初期化

signatureUrlV4.js

Browser.js

初期化

Python

初期化

auth.py

Go

OSSClientインスタンスの設定

v4.go

C++

初期化

SignerV4.cc

C

初期化

oss_auth.c

URL署名

  • 例:

    https://examplebucket.oss-cn-hangzhou.aliyuncs.com/exampleobject?x-oss-additional-headers=host&x-oss-credential=LTAI********************%2F20241203%2Fcn-hangzhou%2Foss%2Faliyun_v4_request&x-oss-date=20241203T034420Z&x-oss-expires=86400&x-oss-signature=70c542eaf652ac291c0c343d63ac24ede41c0526661d9d4c63c0906a2686160c&x-oss-signature-version=OSS4-HMAC-SHA256

    読みやすくするために、上記のURLのx-oss-credentialパラメーターのフィールドはスラッシュ (/) で区切ります。 リクエストを開始すると、URLのスラッシュ (/) をURIエンコードして % 2Fに変換します。 例:

    &x-oss-credential=<AccessKeyId>%2F20241203%2Fcn-hangzhou%2Foss%2Faliyun_v4_request
  • クエリ文字列パラメーター

    パラメーター

    必須 / 任意

    説明

    x-oss-signature-version

    String

    対象

    OSS4-HMAC-SHA256

    署名のバージョンと署名の計算に使用されるアルゴリズム。 値をOSS4-HMAC-SHA256に設定します。

    x-oss-credential

    String

    対象

    LTAI ********************/20241203/cn-hangzhou/oss/aliyun_v4_request

    署名の計算に使用できる資格情報。 形式:

    LTAI********************/<date>/<region>/oss/aliyun_v4_request
    • AccessKeyId: AccessKeyペアのAccessKey ID。

    • date: リクエストが開始された日付。

    • region: 要求されたリソースが存在するリージョン。

    • oss: 要求されたサービスの名前。 値をossに設定します。

    • aliyun_v4_request: リクエスト内の署名バージョンの説明。 値をaliyun_v4_requestに設定します。

    x-oss-date

    String

    対象

    20241203T034420Z

    URLが署名された時刻。 時間はISO 8601標準に従います。 時間差を避けるために、URLが署名されてから15分のオフセットが許可されています。

    説明

    時間は、文字列が署名するためのタイムスタンプとして使用されます。 値は、派生署名キーの日付フィールドの値と同じでなければなりません。

    x-oss-expires

    Integer

    対象

    3600

    署名付きURLの有効期間。 単位は秒です。 最小値:1 最大値: 604800。

    x-oss-additional-headers

    String

    任意

    host

    署名を計算するために追加するヘッダー。 たとえば、ホストヘッダーを追加できます。 このようにして、要求が開始されるドメイン名を変更することはできない。

    次の項目は、ヘッダーを作成するための要件を示します。

    • x-oss-additional-headersパラメーターのヘッダーはすべて小文字である必要があります。

    • x-oss-additional-headersパラメーターのすべてのヘッダーは、アルファベット順にソートする必要があります。

    • 配列内のすべてのヘッダーは、文字列を取得するためにセミコロン (;) で区切られます。

    x-oss-signature

    String

    対象

    77Dv ***************

    署名検証の説明。 x-oss-signatureパラメーターは署名の計算には含まれません。

    x-oss-security-token

    String

    任意

    CAIS ********************************

    security token Service (STS) によって発行されたセキュリティトークン。 このパラメーターは、セキュリティトークンを使用してURLの署名を計算する場合にのみ必要です。

署名計算プロセス

image

URLの署名を計算するために使用される方法は、Authorizationヘッダーの署名を計算するために使用される方法と同様である。 次の項目は、2つの方法の違いを説明します。

  • ペイロードハッシュを記述するx-oss-content-sha256ヘッダーは、URLの署名の計算には使用されません。 署名付きURLを作成する場合、ペイロードの内容を評価することはできません。 代わりに、UNSIGNED-PAYLOADが使用されます。

  • 署名付きURLのクエリ文字列パラメーターのキーが署名されるヘッダーと同じで、値が異なる場合、エラーが報告されます。 キーに複数の値がある場合、キーのすべての値が同時に比較されます。 値が異なる場合、エラーが報告されます。

  • STSから取得したアクセス資格情報を使用して署名付きURLのOSSリソースにアクセスする場合は、x-oss-security-tokenパラメーターをURLのクエリ文字列に追加する必要があります。

  • クエリ文字列のx-oss-signatureパラメーターは署名計算に含まれません。

ステップ1: 正規リクエストを作成する

リクエストのコンテンツを標準形式に変換します。

Format

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

次の表に、上記のパラメーターを示します。

パラメーター

必須 / 任意

値の例

説明

HTTP動詞

列挙

対象

GET

HTTPメソッド。PUT、GET、POST、HEAD、DELETE、またはOPTIONSを使用できます。

正規URI

String

対象

/examplebucket/exampleobject

URIエンコードされた文字列。 絶対パスでスラッシュ (/) をエンコードしないでください。

  • URIは、クエリ文字列パラメーターが含まれていない場合、文字列の最後までドメイン名に続くスラッシュ (/) で始まります。

  • URIは、ドメイン名に続くスラッシュ (/) で始まり、クエリ文字列パラメーターが含まれている場合は疑問符 (?) で終わります。

次の項目では、リクエストURIに含まれるリソースに基づいて正規URIを指定する方法について説明します。

  • リクエストURIにバケット名とオブジェクト名の両方が含まれている場合、正規URIは次の形式になります。

    /examplebucket/exampleobjectを使用します。

  • リクエストURIにバケット名のみが含まれる場合、正規URIの形式は /examplebucket/ です。

  • リクエストURIにオブジェクト名のみが含まれている場合、正規URIは /に設定されます。

正規クエリ文字列Canonical Query String

String

対象

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

URIエンコードされたクエリ文字列パラメーター。 各キーと値を個別にURIエンコードする必要があります。

  • パラメーターをエンコードした後、正規クエリ文字列のパラメーターをキー名でアルファベット順に並べ替えます。 同一のキーが存在する場合は、追加された時刻に基づいて時系列でソートします。

  • キーに値がない場合は、キーのみを追加します。

  • リクエストにクエリ文字列が含まれていない場合は、正規クエリ文字列を空の文字列 ("") に設定します。 最後に改行を追加する必要があります。

  • 署名付きURLのクエリ文字列パラメーターのキーが署名されるヘッダーと同じで、値が異なる場合、エラーが報告されます。 キーに複数の値がある場合、キーのすべての値が同時に比較されます。 値が異なる場合、エラーが報告されます。

Canonicalヘッダー

String

対象

ホスト:

examplebucket.oss-cn-hangzhou.aliyuncs.com

x-oss-content-sha256:

eee300fa39f52127a02af5f9bb86c0fd8b6776fc19101d9a6a7982c9d0edcc04

x-oss-date:

20241203T034420Z

リクエストヘッダーのリストを標準形式に変換した文字列。 文字列の末尾に改行を追加します。

  • ヘッダーキーと値はコロン (:) で区切り、ヘッダーは改行で区切ります。

  • ヘッダーキーは小文字で、アルファベット順に並べ替える必要があります。 ヘッダー値の先頭または末尾のスペースをトリミングする必要があります。

  • ヘッダーキーはアルファベット順にソートされます。

  • リクエスト時間は、x-oss-dateヘッダーで指定します。 時間はISO 8601標準に従い、UTCで表示されます。 例: 20241203T034420Z。

  • ペイロードハッシュを記述するx-oss-content-sha256ヘッダーは、URLの署名の計算には使用されません。 署名付きURLを作成する場合、ペイロードの内容を評価することはできません。 代わりに、UNSIGNED-PAYLOADが使用されます。

Canonicalヘッダーは2つのタイプに分けられます。

  • 追加ヘッダーで指定され、署名計算に使用されるヘッダー

  • リクエストに含まれている場合にCanonicalヘッダーに追加する必要があるヘッダー:

    • Content-Type

    • Content-MD5

    • x-oss-*

追加ヘッダー

String

対象

content-length; ホスト

署名を計算するために追加するヘッダー。 すべてのヘッダーキーは小文字で、アルファベット順に並べ替える必要があります。

ハッシュペイロード

String

対象

UNSIGNED-PAYLOAD

有効値: UNSIGNED-PAYLOAD

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

ステップ2: 署名する文字列の作成

次の文字列を連結して、署名する文字列を作成します。

  • Format

    "OSS4-HMAC-SHA256" + "\n" +
    dateTimeStr + "\n" +
    dateStr + "\n" +
    DigestUtils.sha256Hex(canonicalRequest);

    次の表に、上記のパラメーターを示します。

    パラメーター

    必須 / 任意

    値の例

    説明

    OSS4-HMAC-SHA256

    列挙

    対象

    OSS4-HMAC-SHA256

    正規リクエストのハッシュを作成するために使用されるアルゴリズム。 値をOSS4-HMAC-SHA256に設定します。

    dateTimeStr

    String

    対象

    20241203T034420Z

    UTCでの現在の時刻。 時間は、ISO 8601規格に従わなければならない。

    dateStr

    String

    対象

    20241203/cn-hangzhou/oss/aliyun_v4_request

    スコープ情報。 これにより、計算された署名が指定されたリージョンとサービスに制限されます。 形式:

    <SignDate>/<リージョン>/oss/aliyun_v4_request

    • SignDate: リクエストが開始された日付。

    • リージョン: 要求されたリソースが存在するリージョン。

    • oss: 要求されたサービスの名前。 値をossに設定します。

    • aliyun_v4_request: リクエスト内の署名バージョンの説明。 値をaliyun_v4_requestに設定します。

    CanonicalRequest

    String

    対象

    GET

    /examplebucket/exampleobject

    x-oss-additional-headers=host&x-oss-credential=LTAI ******************** % 2F20241203% 2Fcn-hangzhou % 2Foss % 2Faliyun_v4_request&x-oss-date=20241203T034420Z&x-oss-expires=86400&x-oss-oss-signature-version=OSS4-HMAC-SHA256

    hos t:examplebucket.oss-cn-hangzhou.aliyuncs.com

    host

    UNSIGNED-PAYLOAD

    ステップ1で作成した文字列。

  • 例:

    String stringToSign = "OSS4-HMAC-SHA256\n" +
                    dateTimeStr + "\n" +
                    dateStr + "/cn-hangzhou/oss/aliyun_v4_request\n" +
                    DigestUtils.sha256Hex(canonicalRequest);

ステップ3: 署名を計算する

署名キーを作成し、署名キーを使用して署名を計算します。

  1. 署名キーを計算します。

    HMAC-SHA256(HMAC-SHA256(HMAC-SHA256(HMAC-SHA256("aliyun_v4" + accesskeysecret).getBytes(), dateStr), Region), "oss"), "aliyun_v4_request");
  2. 署名を計算します。

    HEX(HMAC-SHA256(SigningKey, StringToSign))

署名の計算例

この例では、署名付きURLが作成されます。 署名付きURLをサードパーティのユーザーと共有して、ユーザーがOSSにデータをアップロードできるようにすることができます。 次のセクションでは、URLにV4署名を含める方法について説明します。

  • パラメーター

    パラメーター

    AccessKeyId

    accesskeyid

    AccessKeySecret

    accesskeysecret

    バケット

    examplebucket

    オブジェクト

    exampleobject

    リージョン

    cn-hangzhou

  • GetObject

    https://examplebucket.oss-cn-hangzhou.aliyuncs.com/exampleobject?x-oss-additional-headers=host&x-oss-credential=LTAI********************%2F20241203%2Fcn-hangzhou%2Foss%2Faliyun_v4_request&x-oss-date=20241203T032307Z&x-oss-expires=86400&x-oss-signature=eee300fa39f52127a02af5f9bb86c0fd8b6776fc19101d9a6a7982c9d0edcc04&x-oss-signature-version=OSS4-HMAC-SHA256
    host:examplebucket.oss-cn-hangzhou.aliyuncs.com

URLにV4署名を含めるには、次の手順を実行します。

  1. 正規のリクエストを作成します。

    String resourcePath = "exampleobject";
            String endpoint = "https://examplebucket.oss-cn-hangzhou.aliyuncs.com";
            String queryString = "x-oss-additional-headers=host&" +
                    "x-oss-credential=" + accesskeyid + "%2F" + dateStr + "%2Fcn-hangzhou%2Foss%2Faliyun_v4_request&" +
                    "x-oss-date=" + dateTimeStr + "&" +
                    "x-oss-expires=86400&" +
                    "x-oss-signature=" + signature + "&" +
                    "x-oss-signature-version=OSS4-HMAC-SHA256";
    
            String urlStr = endpoint + "/" + resourcePath + "?" + queryString;
            URL url = new URL(urlStr);
  2. 署名する文字列を作成します。

    String stringToSign = "OSS4-HMAC-SHA256\n" +
        dateTimeStr + "\n" +
        dateStr + "/cn-hangzhou/oss/aliyun_v4_request\n" +
        DigestUtils.sha256Hex(canonicalRequest);
  3. 署名を計算します。

    1. 署名キーを計算します。

      説明

      読みやすくするために、次の例では署名キーのBase64-encoded値について説明します。

       dateKey = hmacsha256(("aliyun_v4" + accesskeysecret).getBytes(), dateStr);
       dateRegionKey = hmacsha256(dateKey, "cn-hangzhou");
       dateRegionServiceKey = hmacsha256(dateRegionKey, "oss");
       signingKey = hmacsha256(dateRegionServiceKey, "aliyun_v4_request");
    2. 署名を計算します。

      result = hmacsha256(signingKey, stringToSign);
      String signature = BinaryUtil.toHex(result);
      signature:eee300fa39f52127a02af5f9bb86c0fd8b6776fc19101d9a6a7982c9d0edcc04
  4. URLに署名を追加します。

    String resourcePath = "exampleobject";
            String endpoint = "https://examplebucket.oss-cn-hangzhou.aliyuncs.com";
            String queryString = "x-oss-additional-headers=host&" +
                    "x-oss-credential=" + accesskeyid + "%2F" + dateStr + "%2Fcn-hangzhou%2Foss%2Faliyun_v4_request&" +
                    "x-oss-date=" + dateTimeStr + "&" +
                    "x-oss-expires=86400&" +
                    "x-oss-signature=" + signature + "&" +
                    "x-oss-signature-version=OSS4-HMAC-SHA256";
    
            String urlStr = endpoint + "/" + resourcePath + "?" + queryString;
            URL url = new URL(urlStr);
            System.out.println("url:" + url);

V4署名付きURLの取得に使用される完全なサンプルコード

前述の署名計算例で提供されているパラメーターは、OSS SDK for Javaを使用してV4署名付きURLを取得する完全なプロセスを説明するために使用されます。

重要

この例は、V4署名付きURLの計算方法を示すためにのみ使用されます。 この例を使用するには、example parametersを必須パラメーターに置き換えます。 たとえば、バケットのパスをバケットの実際のパスに置き換え、regionパラメーターのcn-hangzhou値を実際のリージョンに置き換えます。

import com.aliyun.oss.common.utils.BinaryUtil;
import org.apache.commons.codec.digest.DigestUtils;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.net.URL;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.TimeZone;

public class Demo {

    /**
     * Signature calculation tool
     *
     * @return url
     */
    public static void main(String[] args) throws Exception {
        // Before you run the sample code, make sure that the OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET environment variables are configured. 
        String accesskeyid =  System.getenv().get("OSS_ACCESS_KEY_ID");
        String accesskeysecret =  System.getenv().get("OSS_ACCESS_KEY_SECRET");
        // Query and display the current time in the ISO 8601 standard.
        ZonedDateTime now = ZonedDateTime.now(TimeZone.getTimeZone("UTC").toZoneId());
        String dateStr = now.format(DateTimeFormatter.ofPattern("yyyyMMdd"));
        String dateTimeStr = now.format(DateTimeFormatter.ofPattern("yyyyMMdd'T'HHmmss'Z'"));
        // Step 1: Create a canonical request. 
        String canonicalRequest =
                "GET\n" +
                        "/examplebucket/exampleobject\n" +
                        "x-oss-additional-headers=host&x-oss-credential=" + accesskeyid + "%2F" + dateStr + "%2Fcn-hangzhou%2Foss%2Faliyun_v4_request&x-oss-date=" + dateTimeStr + "&x-oss-expires=86400&x-oss-signature-version=OSS4-HMAC-SHA256\n" +
                        "host:examplebucket.oss-cn-hangzhou.aliyuncs.com\n" +
                        "\n" +
                        "host\n" +
                        "UNSIGNED-PAYLOAD";
        System.out.println("canonicalRequest:" + canonicalRequest);
        // Step 2: Create a string to sign. 
        String stringToSign = "OSS4-HMAC-SHA256\n" +
                dateTimeStr + "\n" +
                dateStr + "/cn-hangzhou/oss/aliyun_v4_request\n" +
                DigestUtils.sha256Hex(canonicalRequest);

        // Step 3: Calculate the signature. 
        byte[] dateKey = hmacsha256(("aliyun_v4" + accesskeysecret).getBytes(), dateStr);
        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);

        // Step 4: Add the signature to the URL. 
        String resourcePath = "exampleobject";
        String endpoint = "https://examplebucket.oss-cn-hangzhou.aliyuncs.com";
        String queryString = "x-oss-additional-headers=host&" +
                "x-oss-credential=" + accesskeyid + "%2F" + dateStr + "%2Fcn-hangzhou%2Foss%2Faliyun_v4_request&" +
                "x-oss-date=" + dateTimeStr + "&" +
                "x-oss-expires=86400&" +
                "x-oss-signature=" + signature + "&" +
                "x-oss-signature-version=OSS4-HMAC-SHA256";

        String urlStr = endpoint + "/" + resourcePath + "?" + queryString;
        URL url = new URL(urlStr);
        System.out.println("url:" + url);
    }

    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);
        }
    }
}

サンプル出力:

signature:eee300fa39f52127a02af5f9bb86c0fd8b6776fc19101d9a6a7982c9d0edcc04
url:https://examplebucket.oss-cn-hangzhou.aliyuncs.com/exampleobject?x-oss-additional-headers=host&x-oss-credential=LTAI********************%2F20241203%2Fcn-hangzhou%2Foss%2Faliyun_v4_request&x-oss-date=20241203T032307Z&x-oss-expires=86400&x-oss-signature=eee300fa39f52127a02af5f9bb86c0fd8b6776fc19101d9a6a7982c9d0edcc04&x-oss-signature-version=OSS4-HMAC-SHA256
説明