本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。
建立已簽署的 AWS API 要求
重要
如果您使用 AWS SDK (請參閱範例程式碼和程式庫
在支援多個簽章版本的區域中,手動簽署要求意味著您必須指定要使用的簽章版本。當您向多區域存取點提供請求時,SDK 和 CLI 會自動切換為使用第 4A 版簽署程序,而不需其他組態。
以下是建立已簽署請求的程序概觀。若要計算簽章,首先需要一個要簽名的字串。然後,您可以使用簽署金鑰計算要簽署的字串的 HMAC-SHA256 雜湊。下圖說明此程序,包括您為簽署建立的字串的各種元件。
![正式請求、要簽署的字串、簽署金鑰和簽章的部分的影像。](images/sigV4-using-auth-header.png)
下表描述圖表中顯示的函數。您需要為這些函數實作程式碼。如需詳細資訊,請參閱 AWS SDK 中的程式碼範例。
函式 | 描述 |
---|---|
|
將字串轉換成小寫。 |
|
小寫基數 16 編碼。 |
|
安全雜湊演算法 (SHA) 加密雜湊函數。 |
|
使用 SHA256 演算法搭配提供的簽署金鑰來計算 HMAC。這是最後的簽章。 |
|
移除任何前置和結尾空格。 |
|
URI 編碼每個字節。 UriEncode()必須執行以下規則:
重要您的開發平台提供的標準 UriEncode 功能可能因為基礎 RFC 中的實作和相關模糊性的差異而無法運作。我們建議您編寫自己的自定義 UriEncode 函數,以確保您的編碼能夠正常工作。 若要查看 Java 中 UriEncode 函數的範例,請參閱 GitHub 網站上的 Java 公用程式 |
注意
簽署請求時,您可以使用 AWS 簽名版本 4 或 AWS
簽名版本 4A。兩者之間的主要差異取決於簽章的計算方式。使用「 AWS 簽名版本 4A」時,簽章不包含區域特定資訊,並使用演算法計算。AWS 4-ECDSA-P256-SHA256
暫時安全憑證
您可以使用 AWS Security Token Service (AWS STS) 提供的臨時安全登入資料,而不是使用長期認證來簽署要求。
當您使用臨時安全憑證時,必須將 X-Amz-Security-Token
新增至授權標頭或查詢字串,以保留工作階段權杖。某些服務會要求您將 X-Amz-Security-Token
新增至正式請求。其他服務只需要您在計算簽章之後於結尾新增 X-Amz-Security-Token
。請查看每個文檔以獲取 AWS 服務 詳細信息。
簽署步驟摘要
步驟 1:建立正式請求
將您的請求內容 (主機、動作、標頭等) 編排為標準正式格式。正式請求就是其中一個用於建立登入字串的輸入。如需詳細資訊,請參閱 AWS API 請求簽名的元素。
步驟 2:建立正式請求雜湊
透過在要求日期、區域和服務執行連續的金鑰加上金鑰的金鑰做為初始雜湊作業的 AWS 金鑰,以衍生簽署金鑰。
步驟 3:建立要簽署的字串
使用正式請求和額外資訊,例如演算法、請求日期、登入資料範圍及正式請求的摘要 (雜湊),建立登入字串。
步驟 4:計算簽章
您衍生簽署金鑰之後,可在登入字串上執行金鑰式雜湊操作,即可計算簽章。使用衍生的金鑰做為此操作的雜湊金鑰。
步驟 5:將簽章新增至請求
在您計算簽章、將簽章加到 HTTP 標頭,或加到請求的查詢字串之後。
步驟 1:建立正式請求
透過串連以下字串 (以換行符號字元分隔) 建立正式請求。這有助於確保您計算的簽名和計 AWS 算的簽名可以相符。
<HTTPMethod>
\n<CanonicalURI>
\n<CanonicalQueryString>
\n<CanonicalHeaders>
\n<SignedHeaders>
\n<HashedPayload>
-
HTTPMethod
– HTTP 方法,例如GET
、PUT
、HEAD
和DELETE
。 -
CanonicalUri
— 絕對路徑元件 URI 的 URI 編碼版本,從網域名稱後面的「/」開始,直到字串結尾或問號字元 ('?') 如果你有查詢字符串參數。如果絕對路徑空白,請使用斜線字元 (/)。下列範例中的 URI/examplebucket/myphoto.jpg
是絕對路徑,您不會在絕對路徑中編碼 "/":http://s3.amazonaws.com/examplebucket/myphoto.jpg
-
CanonicalQueryString
— URI 編碼的查詢字串參數。您可以個別對每個名稱和值進行 URI 編碼。您還必須依索引鍵名稱的字母順序來排序正式查詢字串中的參數。編碼後進行排序。下列 URI 範例中的查詢字串為:http://s3.amazonaws.com/examplebucket?prefix=somePrefix&marker=someMarker&max-keys=2
正式查詢字串如下所示 (為了便於閱讀,向此範例新增了分行符號):
UriEncode("marker")+"="+UriEncode("someMarker")+"&"+ UriEncode("max-keys")+"="+UriEncode("20") + "&" + UriEncode("prefix")+"="+UriEncode("somePrefix")
請求以子資源為目標時,對應的查詢參數值將是空字串 ("")。例如,下列 URI 會識別
examplebucket
儲存貯體上的ACL
子資源:http://s3.amazonaws.com/examplebucket?acl
CanonicalQueryString 在這種情況下,如下所示:
UriEncode("acl") + "=" + ""
如果 URI 不包含 '?',則請求中沒有查詢字串,並且您將正式查詢字串設定為空字串 ("")。您仍然需要包含 "\n"。
-
CanonicalHeaders
— 請求標頭及其值的清單。個別標頭名稱和值對以新行字元 ("\n") 分隔。以下是 canonicalheader 的範例:Lowercase(
<HeaderName1>
)+":"+Trim(<value>
)+"\n" Lowercase(<HeaderName2>
)+":"+Trim(<value>
)+"\n" ... Lowercase(<HeaderNameN>
)+":"+Trim(<value>
)+"\n"CanonicalHeaders 列表必須包括以下內容:
-
HTTP
host
標頭。 -
如果標
Content-Type
頭存在於請求中,則必須將其添加到CanonicalHeaders
列表中。 -
還必須新增您計劃包含在請求中的任何
x-amz-*
標頭。例如,如果您使用的是暫時安全憑證,需要將x-amz-security-token
包含在您的請求中。您必須在的清單中新增此標頭CanonicalHeaders
。
注意
Amazon S3 AWS 請求需要
x-amz-content-sha256
標頭。其提供請求承載的雜湊。如果沒有承載,您必須提供空字串的雜湊。每個標頭名稱必須:
-
使用小寫字元。
-
依字母順序顯示。
-
後接冒號 (:)。
對於值,您必須:
-
修剪任何前置或結尾空格。
-
將連續空格轉換為單一空格。
-
使用逗號分隔多值標頭的值。
-
簽章中必須包含主機標頭 (HTTP/1.1) 或 :authority 標頭 (HTTP/2),以及簽章中的任何
x-amz-*
標頭。可以選擇性地在簽章中包含其他標準標頭,例如 content-type。
本範例中使用的
Lowercase()
和Trim()
函數在上一節中進行了描述。以下是
CanonicalHeaders
字串範例。標頭名稱為小寫且已排序。host:s3.amazonaws.com x-amz-content-sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 x-amz-date:20130708T220855Z
注意
對於計算授權簽章而言,僅需要主機和任何
x-amz-*
標頭;但是,為了防止資料竄改,您應考慮在簽章計算中包含所有標頭。 -
-
SignedHeaders
— 按字母順序排序、以分號分隔的小寫要求標頭名稱清單。清單中的請求標頭與您在CanonicalHeaders
字串中包含的標頭相同。例如,對於上一個範例,的值SignedHeaders
將如下所示:host;x-amz-content-sha256;x-amz-date
-
HashedPayload
— 使用 HTTP 要求主體中的有效負載建立的字串,做為雜湊函數的輸入。此字串使用小寫十六進位字元。Hex(SHA256Hash(
<payload>
)如果請求中沒有承載,則計算空字串的雜湊,如下所示:
Hex(SHA256Hash(""))
雜湊會傳回下列值:
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
例如,使用 PUT 請求上傳物件時,請在主體中提供物件資料。使用
GET
請求擷取物件時,請計算空字串雜湊。
步驟 2:建立正式請求雜湊
使用與您用來建立承載雜湊相同的演算法,建立正式請求的雜湊 (摘要)。正式請求的雜湊是小寫十六進位字元字串。
步驟 3:建立登入字串
透過串連以下字串 (以換行符號字元分隔) 建立字串。請勿以換行符號字元結束此字串。
Algorithm
\n
RequestDateTime
\n
CredentialScope
\n
HashedCanonicalRequest
-
Algorithm
- 用來建立正式請求雜湊的演算法。對於 SHA-256 而言,演算法為AWS4-HMAC-SHA256
。 -
RequestDateTime
— 認證範圍中使用的日期和時間。此值是 ISO 8601 格式的目前 UTC 時間 (例如,20130524T000000Z
)。 -
CredentialScope
— 認證範圍。這會將產生的簽章限制到指定的區域和服務。該字串具有以下格式:YYYYMMDD
/region
/service
/aws4_request。 -
HashedCanonicalRequest
— 規範要求的雜湊值。此值是在步驟 2 中計算的。
以下是登入字串範例。
"AWS4-HMAC-SHA256" + "\n" +
timeStampISO8601Format + "\n" +
<Scope>
+ "\n" +
Hex(SHA256Hash(<CanonicalRequest>
))
步驟 4:計算簽章
在 S AWS ignature Version 版本 4 中,您不需要使用 AWS 存取金鑰來簽署請求,而是建立範圍為特定區域和服務的簽署金鑰,做為要新增至要求的驗證資訊。
DateKey = HMAC-SHA256("AWS4"+"
<SecretAccessKey>
", "<YYYYMMDD>
") DateRegionKey = HMAC-SHA256(<DateKey>
, "<aws-region>
") DateRegionServiceKey = HMAC-SHA256(<DateRegionKey>
, "<aws-service>
") SigningKey = HMAC-SHA256(<DateRegionServiceKey>
, "aws4_request")
如需區域字串清單,請參閱《AWS 一般參考》中的區域端點。
對於每個步驟,使用所需金鑰和資料呼叫雜湊函數。對雜湊函數的每次呼叫結果都會變成雜湊函數的下一次呼叫輸入。
需要輸入
-
包含私密存取金鑰的字串
Key
-
字串
Date
,其中包含憑證範圍中使用的日期,格式為 YYYYMMDD -
包含區域代碼 (例如,
us-east-1
) 的字串Region
-
包含服務代碼 (例如,
ec2
) 的字串Service
-
在之前步驟中建立的登入字串。
若要計算簽章。
-
串連 "AWS4" 和私密存取金鑰。呼叫雜湊函數,將串連的字串作為索引鍵,日期字串做為資料。
kDate = hash("AWS4" + Key, Date)
-
呼叫雜湊函數,將上一次呼叫的結果作為索引鍵,區域字串作為資料。
kRegion = hash(kDate, Region)
-
呼叫雜湊函數,將上一次呼叫的結果作為索引鍵,服務字串作為資料。
kService = hash(kRegion, Service)
-
呼叫雜湊函數,將上一次呼叫的結果作為索引鍵,"aws4_request" 作為資料。
kSigning = hash(kService, "aws4_request")
-
呼叫雜湊函數,將上一次呼叫的結果作為索引鍵,登入字串作為資料。結果是作為二進位值的簽章。
signature = hash(kSigning,
string-to-sign
) -
將簽章的表示形式從二進位轉換為十六進位,使用小寫字元。
步驟 5:將簽章新增至請求
範例:授權標頭
以下範例顯示針對 DescribeInstances
動作的 Authorization
標頭。為了便於閱讀,此範例使用換行符號進行格式化。在代碼中,這必須是一個連續字串。演算法和 Credential
之間沒有逗號。但是,必須使用逗號分隔其他元素。
Authorization: AWS4-HMAC-SHA256
Credential=AKIAIOSFODNN7EXAMPLE/20220830/us-east-1/ec2/aws4_request,
SignedHeaders=host;x-amz-date,
Signature=calculated-signature
範例:查詢字串中包含身分驗證參數的請求
以下範例顯示針對 DescribeInstances
動作的查詢,其中包含身分驗證資訊。為了便於閱讀,此範例使用換行符號進行格式化,而不是 URL 編碼。在程式碼中,查詢字串必須是 URL 編碼的連續字串。
https://ec2.amazonaws.com/?
Action=DescribeInstances&
Version=2016-11-15&
X-Amz-Algorithm=AWS4-HMAC-SHA256&
X-Amz-Credential=AKIAIOSFODNN7EXAMPLE/20220830/us-east-1/ec2/aws4_request&
X-Amz-Date=20220830T123600Z&
X-Amz-SignedHeaders=host;x-amz-date&
X-Amz-Signature=calculated-signature
AWS 軟體開發套件中的原始程式碼
AWS SDK 包含 GitHub 用於簽署 AWS API 要求的原始程式碼。如需程式碼範例,請參閱 範例儲存庫中的 AWS 範例專案
-
AWS SDK for .NET — AWS4Signer.cs
-
AWS SDK for C++ — AWSAuthV4Signer. CPP
-
AWS SDK for Go — v4.go
-
AWS SDK for Java — BaseAws4Signer.java
-
AWS SDK for JavaScript — v4.js
-
AWS SDK for PHP — SignatureV4.php
-
AWS SDK for Python (Boto) — signers.py
-
AWS SDK for Ruby — 簽名者