View a markdown version of this page

授權標頭的簽章計算:以多個區塊傳輸承載 (區塊上傳)AWS (簽章版本 4) - Amazon Simple Storage Service

本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。

授權標頭的簽章計算:以多個區塊傳輸承載 (區塊上傳)AWS (簽章版本 4)

如中所述概觀,使用 Authorization標頭驗證請求時,您可以選擇以區塊形式上傳承載。您可以使用固定大小或可變大小區塊來傳送資料。本節說明區塊上傳中的簽章計算程序、如何建立區塊內文,以及延遲簽署如何在您第一次上傳區塊的位置運作,並在後續區塊中傳送其簽章。範例區段 (請參閱 範例:PUT 物件) 顯示簽章計算和產生的Authorization標頭,您可以將其做為測試套件來驗證程式碼。

注意

在一系列區塊中傳輸資料時,您必須執行下列其中一項操作:

  • 使用 Content-Length HTTP 標頭明確指定總內容長度 (物件長度以位元組為單位,加上每個區塊中的中繼資料)。若要這樣做,您必須在開始請求之前預先計算承載的總長度,包括您在每個區塊中傳送的中繼資料。

  • 指定 Transfer-Encoding HTTP 標頭。如果您包含 Transfer-Encoding標頭並指定 以外的任何值identity,則必須省略 Content-Length標頭。

對於所有請求,您必須包含 x-amz-decoded-content-length標頭,以位元組為單位指定物件的大小。

每個區塊簽章計算都包含上一個區塊的簽章。若要開始,請僅使用 標頭建立種子簽章。您可以在第一個區塊的簽章計算中使用種子簽章。對於每個後續區塊,您可以建立包含上一個區塊簽章的區塊簽章。因此,區塊簽章會鏈結在一起;也就是說,區塊 n 的簽章是函數 F(區塊 n,簽章 (區塊 n-1))。鏈結可確保您以正確的順序傳送區塊。

若要執行區塊上傳,請執行下列動作:

  1. 決定承載區塊大小。撰寫程式碼時需要此項目。

    區塊大小必須至少為 8 KB。我們建議區塊大小至少為 64 KB,以獲得更好的效能。此區塊大小適用於除最後一個區塊以外的所有區塊。您傳送的最後一個區塊可以小於 8 KB。如果您的承載很小,可以放入一個區塊中,則它可以小於 8 KB。

  2. 建立要包含在第一個區塊中的種子簽章。如需詳細資訊,請參閱計算種子簽章

  3. 建立第一個區塊並將其串流。如需詳細資訊,請參閱定義區塊內文

  4. 對於每個後續區塊,計算包含您簽署字串中先前簽章的區塊簽章,建構區塊並傳送。如需詳細資訊,請參閱定義區塊內文

  5. 傳送最終的額外區塊,這與建構中的其他區塊相同,但資料位元組為零。如需詳細資訊,請參閱定義區塊內文

計算種子簽章

下圖說明計算種子簽章的程序。

計算種子簽章的程序。

下表描述圖表中顯示的函數。您需要為這些函數實作程式碼。

函式 說明
Lowercase() 將字串轉換成小寫。
Hex() 小寫基數 16 編碼。
SHA256Hash() 安全雜湊演算法 (SHA) 加密雜湊函數。
HMAC-SHA256() 使用 SHA256 演算法搭配提供的簽署金鑰來計算 HMAC。這是最後的簽章。
Trim() 移除任何前置和結尾空格。
UriEncode()

URI 編碼每個位元組。UriEncode() 必須強制執行下列規則:

  • URI 對除未預留字元之外的每個位元組進行編碼:'A'-'Z', 'a'-'z', '0'-'9', '-', '.', '_', and '~'。

  • 空格字元是預留字元,必須編碼為 "%20" (而不是 "+")。

  • 每個 URI 編碼的位元組都是由 '%' 和位元組的兩位數十六進位值組成。

  • 十六進位值中的字母必須為大寫,例如 "%1A"。

  • 對所有位置的正斜線字元 '/' 進行編碼 (物件索引鍵名稱除外)。例如,如果物件索引鍵名稱為 photos/Jan/sample.jpg,則不會對索引鍵名稱中的正斜線進行編碼。

重要

由於基礎 RFC 中的實作差異和相關模糊性,您的開發平台提供的標準 UriEncode 函數可能無法工作。我們建議您編寫自己的自訂 UriEncode 函數,以確保您的編碼能夠正常工作。

以下是 Java 中的 UriEncode() 函數範例。

public static String UriEncode(CharSequence input, boolean encodeSlash) { StringBuilder result = new StringBuilder(); for (int i = 0; i < input.length(); i++) { char ch = input.charAt(i); if ((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') || (ch >= '0' && ch <= '9') || ch == '_' || ch == '-' || ch == '~' || ch == '.') { result.append(ch); } else if (ch == '/') { result.append(encodeSlash ? "%2F" : ch); } else { result.append(toHexUTF8(ch)); } } return result.toString(); }

如需簽署程序的相關資訊,請參閱 授權標頭的簽章計算:在單一區塊中傳輸承載AWS (簽章第 4 版)。程序相同,但 的建立CanonicalRequest不同,如下所示:

  • 除了您計劃新增的請求標頭之外,您還必須包含下列標頭:

    標頭 說明
    x-amz-content-sha256

    所有 AWS Signature 第 4 版請求都需要此標頭。將 值設定為 ,STREAMING-AWS4-HMAC-SHA256-PAYLOAD表示簽章僅涵蓋標頭,而且沒有承載。

    Content-Encoding

    將值設定為 aws-chunked

    Amazon S3 支援多個內容編碼值。您可以在使用 Signature 第 4 版串流 API 時指定自訂內容編碼。

    例如:

    Content-Encoding : aws-chunked,gzip

    Amazon S3 會將沒有aws-chunked值的產生物件存放在 content-encoding 標頭中。如果 aws-chunked是您在 content-encoding標頭中傳遞的唯一值,S3 會將content-encoding標頭視為空白,而且不會在擷取物件時傳回此標頭。

    x-amz-decoded-content-length 將值設定為要區塊化之資料的長度,以位元組為單位,而不計算任何中繼資料。例如,如果您要上傳 4 GB 檔案,請將 值設定為 4294967296。這是要上傳之物件的原始大小 (您要存放在 Amazon S3 中的資料)。
    Content-Length

    將值設定為已傳輸 HTTP 內文的實際大小,其中包括資料的長度 (為 設定的值x-amz-decoded-content-length),以及區塊中繼資料。每個區塊都有中繼資料,例如上一個區塊的簽章。區塊計算會在下一節中討論。如果您包含 Transfer-Encoding標頭並指定 以外的任何值identity,則不得包含 Content-Length標頭。

您使用種子簽章傳送第一個區塊。您必須建構區塊,如下節所述。

定義區塊內文

所有區塊都包含一些中繼資料。每個區塊必須符合下列結構:

string(IntHexBase(chunk-size)) + ";chunk-signature=" + signature + \r\n + chunk-data + \r\n

其中:

  • IntHexBase() 是您寫入以將整數區塊大小轉換為十六進位的函數。例如,如果區塊大小為 65536,則十六進位字串為 "10000"。

  • 區塊大小是不含中繼資料的區塊資料大小,以位元組為單位。例如,如果您上傳 65 KB 物件並使用 64 KB 的區塊大小,則會以三個區塊上傳資料:第一個為 64 KB,第二個為 1 KB,最後一個區塊為 0 位元組。

  • 簽章 對於每個區塊,您可以使用下列字串來計算簽章。對於第一個區塊,您可以使用 seed-signature 作為先前的簽章。

    計算種子簽章的程序,其中顯示要簽署之字串的各種元件。

您傳送的最終區塊資料大小為 0,雖然區塊內文仍包含中繼資料,包括先前區塊的簽章。

範例:PUT 物件

您可以使用本節中的範例做為參考,以檢查程式碼中的簽章計算。檢閱範例之前,請注意下列事項:

  • 這些範例中的簽章計算使用以下範例安全登入資料。

    參數 Value
    AWSAccessKeyId AKIAIOSFODNN7EXAMPLE
    AWSSecretAccessKey wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
  • 所有範例都使用請求時間戳記 20130524T000000Z (Fri, 24 May 2013 00:00:00 GMT)。

  • 所有範例都會使用 examplebucket做為儲存貯體名稱。

  • 儲存貯體假設位於美國東部 (維吉尼亞北部) 區域,而登入資料ScopeSigning Key計算會使用 us-east-1做為區域指標。 如需詳細資訊,請參閱 Amazon Web Services 一般參考中的區域與端點

  • 您可以使用路徑樣式或虛擬託管樣式請求。下列範例使用虛擬託管樣式請求,例如:

    https://examplebucket.s3.amazonaws.com/photos/photo1.jpg

    如需詳細資訊,請參閱《Amazon Simple Storage Service 使用者指南》中的儲存貯體虛擬託管

下列範例會傳送上傳物件的PUT請求。簽章計算假設如下:

  • 您正在上傳 65 KB 文字檔案,而檔案內容是由字母 'a' 組成的單字元字串。

  • 區塊大小為 64 KB。因此,承載會以三個區塊上傳:64 KB、1 KB,以及具有 0 個位元組區塊資料的最終區塊。

  • 產生的物件具有金鑰名稱 chunkObject.txt

  • 您透過新增請求標頭來x-amz-storage-class請求 REDUCED_REDUNDANCY 做為儲存體方案。

如需 API 動作的相關資訊,請參閱 PutObject。一般請求語法如下:

PUT /examplebucket/chunkObject.txt HTTP/1.1 Host: s3.amazonaws.com x-amz-date: 20130524T000000Z x-amz-storage-class: REDUCED_REDUNDANCY Authorization: SignatureToBeCalculated x-amz-content-sha256: STREAMING-AWS4-HMAC-SHA256-PAYLOAD Content-Encoding: aws-chunked x-amz-decoded-content-length: 66560 Content-Length: 66824 <Payload>

下列步驟顯示簽章計算。

  1. 種子簽章 — 建立要簽署的字串
    1. CanonicalRequest

      PUT /examplebucket/chunkObject.txt content-encoding:aws-chunked content-length:66824 host:s3.amazonaws.com x-amz-content-sha256:STREAMING-AWS4-HMAC-SHA256-PAYLOAD x-amz-date:20130524T000000Z x-amz-decoded-content-length:66560 x-amz-storage-class:REDUCED_REDUNDANCY content-encoding;content-length;host;x-amz-content-sha256;x-amz-date;x-amz-decoded-content-length;x-amz-storage-class STREAMING-AWS4-HMAC-SHA256-PAYLOAD

      在正式請求中,第三行是空的,因為請求中沒有查詢參數。最後一行是做為雜湊承載值提供的常數字串,應該與 的值相同x-amz-content-sha256 header

    2. StringToSign

      AWS4-HMAC-SHA256 20130524T000000Z 20130524/us-east-1/s3/aws4_request cee3fed04b70f867d036f722359b0b1f2f0e5dc0efadbc082b76c4c60e316455

      注意

      如需有關要簽署之字串中每一行的資訊,請參閱說明種子簽章計算的圖表。

  2. SigningKey

    signing key = HMAC-SHA256(HMAC-SHA256(HMAC-SHA256(HMAC-SHA256("AWS4" + "<YourSecretAccessKey>","20130524"),"us-east-1"),"s3"),"aws4_request")

  3. 種子簽章

    4f232c4386841ef735655705268965c44a0e4690baa4adea153f7db9fa80a0a9

  4. 授權標頭

    產生的授權標頭如下所示:

    AWS4-HMAC-SHA256 Credential=AKIAIOSFODNN7EXAMPLE/20130524/us-east-1/s3/aws4_request,SignedHeaders=content-encoding;content-length;host;x-amz-content-sha256;x-amz-date;x-amz-decoded-content-length;x-amz-storage-class,Signature=4f232c4386841ef735655705268965c44a0e4690baa4adea153f7db9fa80a0a9

  5. 區塊 1:(65536 位元組,值 97 表示字母 'a')
    1. 要簽署的區塊字串:

      AWS4-HMAC-SHA256-PAYLOAD 20130524T000000Z 20130524/us-east-1/s3/aws4_request 4f232c4386841ef735655705268965c44a0e4690baa4adea153f7db9fa80a0a9 e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 bf718b6f653bebc184e1479f1935b8da974d701b893afcf49e701f3e2f9f9c5a

      注意

      如需有關要簽署之字串中每一行的資訊,請參閱上圖,其中顯示要簽署之字串的各種元件 (例如,最後三行為 、 previous-signaturehash("")hash(current-chunk-data))。

    2. 區塊簽章:

      ad80c730a21e5b8d04586a2213dd63b9a0e99e0e2307b0ade35a65485a288648
    3. 已傳送的區塊資料:

      10000;chunk-signature=ad80c730a21e5b8d04586a2213dd63b9a0e99e0e2307b0ade35a65485a288648 <65536-bytes>
  6. 區塊 2:(1024 個位元組,值 97 表示字母 'a')
    1. 要簽署的區塊字串:

      AWS4-HMAC-SHA256-PAYLOAD 20130524T000000Z 20130524/us-east-1/s3/aws4_request ad80c730a21e5b8d04586a2213dd63b9a0e99e0e2307b0ade35a65485a288648 e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 2edc986847e209b4016e141a6dc8716d3207350f416969382d431539bf292e4a
    2. 區塊簽章:

      0055627c9e194cb4542bae2aa5492e3c1575bbb81b612b7d234b86a503ef5497
    3. 已傳送的區塊資料:

      400;chunk-signature=0055627c9e194cb4542bae2aa5492e3c1575bbb81b612b7d234b86a503ef5497 <1024 bytes>
  7. 區塊 3:(0 位元組資料)
    1. 要簽署的區塊字串:

      AWS4-HMAC-SHA256-PAYLOAD 20130524T000000Z 20130524/us-east-1/s3/aws4_request 0055627c9e194cb4542bae2aa5492e3c1575bbb81b612b7d234b86a503ef5497 e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
    2. 區塊簽章:

      b6c6ea8a5354eaf15b3cb7646744f4275b71ea724fed81ceb9323e279d449df9
    3. 已傳送的區塊資料:

      0;chunk-signature=b6c6ea8a5354eaf15b3cb7646744f4275b71ea724fed81ceb9323e279d449df9