本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。
重要
如果您使用 AWS SDK (請參閱範例程式碼和程式庫
在支援多個簽章版本的區域中,手動簽署要求意味著您必須指定要使用的簽章版本。當您向多區域存取點提供請求時,SDK 和 CLI 會自動切換為使用第 4A 版簽署程序,而不需其他組態。
您可以使用 AWS SigV4 簽署通訊協定來建立 AWS API 請求的簽署請求。
-
根據請求詳細資訊來建立正式請求。
-
使用您的 AWS 登入資料計算簽章。
-
將此簽章作為授權標頭新增至請求。
AWS 然後複寫此程序,並驗證簽章、授予或拒絕相應存取。
若要了解如何使用 AWS SigV4 簽署 API 請求,請參閱 請求簽章範例。
下表說明在建立已簽署請求的過程中所使用的函數。您需要為這些函數實作程式碼。如需詳細資訊,請參閱 AWS SDK 中的程式碼範例。
函式 | 描述 |
---|---|
|
將字串轉換成小寫。 |
|
小寫基數 16 編碼。 |
|
安全雜湊演算法 (SHA) 加密雜湊函數。 |
|
使用 SHA256 演算法搭配提供的簽署金鑰來計算 HMAC。這是您使用 SigV4 簽署時的最終簽章。 |
|
橢圓曲線數位簽章演算法 (ECDSA) 簽章,其計算方式是使用以公有私有金鑰密碼編譯為基礎的非對稱簽章。 |
|
使用 NIST SP800-108r1 中定義的 PRF 函數 HMAC-SHA256,在計數器模式中的 NIST SP800-108 KDF。 https://doi.org/10.6028/NIST.SP.800-108r1-upd1 |
|
八位元組到整數函數,如 ANSI X9.62 中所述。 |
|
移除任何前置和結尾空格。 |
|
URI 編碼每個位元組。UriEncode() 必須強制執行下列規則:
重要由於基礎 RFC 中的實作差異和相關模糊性,您的開發平台提供的標準 UriEncode 函數可能無法工作。我們建議您編寫自己的自訂 UriEncode 函數,以確保您的編碼能夠正常工作。 若要查看 Java 中的 UriEncode 函數範例,請參閱 GitHub 網站上的 Java 公用程式 |
注意
簽署請求時,您可以使用 AWS SigV4 或 AWS SigV4a。兩者之間的主要差異取決於簽章的計算方式。使用 SigV4a,區域集會包含在要簽署的字串中,但不屬於登入資料衍生步驟。
具有臨時安全憑證的簽署請求
您可以使用 AWS Security Token Service () 提供的臨時安全登入資料,而不是使用長期登入資料來簽署請求AWS STS。
當您使用臨時安全憑證時,必須將 X-Amz-Security-Token
新增至授權標頭或將它包含在查詢字串中,以保留工作階段權杖。某些服務會要求您將 X-Amz-Security-Token
新增至正式請求。其他服務只需要您在計算簽章之後於結尾新增 X-Amz-Security-Token
。檢查每個 的文件 AWS 服務 ,了解特定需求。
簽署步驟摘要
建立正式請求
將您的請求內容 (主機、動作、標頭等) 編排為標準正式格式。正式請求就是其中一個用於建立登入字串的輸入。如需有關建立正式請求的詳細資訊,請參閱 AWS API 請求簽章的元素。
建立正式請求的雜湊
使用與您用來建立承載雜湊相同的演算法,對正式請求進行雜湊。正式請求的雜湊是小寫十六進位字元字串。
建立要簽署的字串
使用正式請求和額外資訊,例如演算法、請求日期、憑證範圍及正式請求的雜湊,建立登入字串。
衍生簽署金鑰
使用秘密存取金鑰衍生用於簽署請求的金鑰。
計算簽章
在字串上執行鍵控雜湊操作,以使用衍生的簽署金鑰作為雜湊金鑰來簽署。
將簽章新增至請求
將計算簽章新增至 HTTP 標頭,或新增至請求的查詢字串。
建立正式請求
若要建立正式請求,請串連以下字串 (以換行符號字元分隔)。這有助於確保您計算的簽章符合 AWS 計算的簽章。
<HTTPMethod>
\n<CanonicalURI>
\n<CanonicalQueryString>
\n<CanonicalHeaders>
\n<SignedHeaders>
\n<HashedPayload>
-
HTTPMethod
– HTTP 方法,例如GET
、PUT
、HEAD
和DELETE
。 -
CanonicalUri
– 絕對路徑元件 URI 的 URI 編碼版本,以/
開頭,後接網域名稱,一直到字串結尾,或者如果具有查詢字串參數,則一直到問號字元 (?
)。如果絕對路徑空白,請使用斜線字元 (/
)。下列範例中的 URI/amzn-s3-demo-bucket/myphoto.jpg
是絕對路徑,您不會在絕對路徑中編碼/
:http://s3.amazonaws.com/amzn-s3-demo-bucket/myphoto.jpg
-
CanonicalQueryString
– URI 編碼的查詢字串參數。您可以單獨對每個名稱和值進行 URI 編碼。您還必須依索引鍵名稱的字母順序來排序正式查詢字串中的參數。編碼後進行排序。下列 URI 範例中的查詢字串為:http://s3.amazonaws.com/amzn-s3-demo-bucket?prefix=somePrefix&marker=someMarker&max-keys=2
正式查詢字串如下所示 (為了便於閱讀,向此範例新增了分行符號):
UriEncode("marker")+"="+UriEncode("someMarker")+"&"+ UriEncode("max-keys")+"="+UriEncode("20") + "&" + UriEncode("prefix")+"="+UriEncode("somePrefix")
請求以子資源為目標時,對應的查詢參數值將是空字串 (
""
)。例如,下列 URI 會識別amzn-s3-demo-bucket
儲存貯體上的ACL
子資源:http://s3.amazonaws.com/amzn-s3-demo-bucket?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
包含在您的請求中。您必須將此標頭新增在CanonicalHeader
的清單中。 -
對於 SigV4a,您必須包含區域集標頭,指定請求將在其中生效的區域集。標頭
X-Amz-Region-Set
指定為逗號分隔值的清單。下列範例顯示允許在 us-east-1 和 us-west-1 區域提出請求的區域標頭。X-Amz-Region-Set=us-east-1,us-west-1
您可以在區域中使用萬用字元 (*) 來指定多個區域。在下列範例中, 標頭允許在 us-west-1 和 us-west-2 中提出請求。
X-Amz-Region-Set=us-west-*
注意
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-*
標頭;不過,為了防止資料竄改,您應該考慮在簽章計算中包含其他標頭。請勿包含跨複雜系統傳輸期間經常變更的hop-by-hop標頭。這包括代理、負載平衡器和分散式系統中節點所變更的所有揮發性傳輸標頭,包括
connection
、、x-amzn-trace-id
、user-agent
keep-alive
、transfer-encoding
TE
、trailer
、upgrade
proxy-authorization
和proxy-authenticate
。 -
-
SignedHeaders
– 依字母順序排序、以分號分隔的小寫請求標頭名稱清單。清單中的請求標頭與您在CanonicalHeaders
字串中包含的標頭相同。對於上一個範例,SignedHeaders
值將如下所示:host;x-amz-content-sha256;x-amz-date
-
HashedPayload
– 使用 HTTP 請求內文中的承載作為雜湊函數的輸入所建立的字串。此字串使用小寫十六進位字元。Hex(SHA256Hash(
<payload>
>))如果請求中沒有承載,您可以計算空字串的雜湊,例如當您使用
GET
請求擷取物件時,承載中沒有任何內容。Hex(SHA256Hash(""))
注意
對於 Amazon S3,請在建構正式請求時包含文字字串
UNSIGNED-PAYLOAD
,並在傳送請求時設定與x-amz-content-sha256
標頭值相同的值。Hex(SHA256Hash("UNSIGNED-PAYLOAD"))
建立正式請求的雜湊
使用與您用來建立承載雜湊相同的演算法,建立正式請求的雜湊 (摘要)。正式請求的雜湊是小寫十六進位字元字串。
建立要簽署的字串
若要建立要簽署的字串,請串連以下字串 (以換行符號字元分隔)。請勿以換行符號字元結束此字串。
Algorithm
\n
RequestDateTime
\n
CredentialScope
\n
HashedCanonicalRequest
-
Algorithm
- 用來建立正式請求雜湊的演算法。-
SigV4 –
AWS4-HMAC-SHA256
用於指定HMAC-SHA256
雜湊演算法。 -
SigV4a –
AWS4-ECDSA-P256-SHA256
用於指定ECDSA-P256-SHA-256
雜湊演算法。
-
-
RequestDateTime
- 憑證範圍中使用的日期和時間。此值是 ISO 8601 格式的目前 UTC 時間 (例如,20130524T000000Z
)。 -
CredentialScope
– 憑證範圍會將產生的簽章限制到指定的區域和服務。-
SigV4 – 登入資料包含您的存取金鑰 ID、
YYYYMMDD
格式日期、區域碼、服務碼和aws4_request
終止字串,以斜線 (/) 分隔。區域代碼、服務代碼和終止字串必須使用小寫字元。字串的格式如下:YYYYMMDD/region/service/aws4_request
。 -
SigV4a – 登入資料包含
YYYYMMDD
格式的日期、服務名稱和aws4_request
終止字串,以斜線 (/) 分隔。請注意,登入資料範圍不包含 區域,因為該區域包含在單獨的標頭 中X-Amz-Region-Set
。字串的格式如下:YYYYMMDD/service/aws4_request
。
-
-
HashedCanonicalRequest
– 在上一步驟中計算的正式請求的雜湊。
以下是登入字串範例。
"<Algorithm>
" + "\n" +
timeStampISO8601Format + "\n" +
<Scope>
+ "\n" +
Hex(<Algorithm>
(<CanonicalRequest>
))
衍生簽署金鑰
若要衍生簽署金鑰,請選擇下列其中一個程序來計算 SigV4 或 SigV4a 的簽署金鑰。
為 SigV4 產生簽署金鑰
若要衍生 SigV4 的簽署金鑰,請在請求日期、區域和服務上執行連續的鍵控雜湊操作 (HMAC),並將 AWS 私密存取金鑰做為初始雜湊操作的金鑰。
對於每個步驟,使用所需金鑰和資料呼叫雜湊函數。對雜湊函數的每次呼叫結果都會變成雜湊函數的下一次呼叫輸入。
下列範例顯示如何衍生此程序下一節中使用的 SigningKey
,顯示您的輸入串連和雜湊的順序。HMAC-SHA256
是用於雜湊資料的雜湊函數,如下所示。
DateKey = HMAC-SHA256("AWS4"+"
<SecretAccessKey>
", "<YYYYMMDD>
") DateRegionKey = HMAC-SHA256(<DateKey>
, "<aws-region>
") DateRegionServiceKey = HMAC-SHA256(<DateRegionKey>
, "<aws-service>
") SigningKey = HMAC-SHA256(<DateRegionServiceKey>
, "aws4_request")
需要輸入
-
Key
– 包含私密存取金鑰的字串。 -
Date
– 包含登入資料範圍中使用的日期的字串,格式為 YYYYMMDD。 -
Region
– 包含區域碼的字串 (例如us-east-1
)。如需區域字串清單,請參閱《AWS 一般參考》中的區域端點。
-
Service
– 包含服務代碼的字串 (例如ec2
)。 -
在之前步驟中建立的登入字串。
衍生 SigV4 的簽署金鑰
-
串連
"AWS4"
和私密存取金鑰。呼叫雜湊函數,將串連的字串作為索引鍵,日期字串做為資料。DateKey = hash("AWS4" + Key, Date)
-
呼叫雜湊函數,將上一次呼叫的結果作為索引鍵,區域字串作為資料。
DateRegionKey = hash(kDate, Region)
-
呼叫雜湊函數,將上一次呼叫的結果作為索引鍵,服務字串作為資料。
服務代碼由服務定義。可以使用 AWS Pricing CLI 中的 get-products
來傳回服務的服務代碼。 DateRegionServiceKey = hash(kRegion, Service)
-
呼叫雜湊函數,將上一次呼叫的結果作為索引鍵,"aws4_request" 作為資料。
SigningKey = hash(kService, "aws4_request")
為 SigV4a 產生簽署金鑰
若要建立 SigV4a 的簽署金鑰,請使用下列程序從秘密存取金鑰衍生金鑰對。如需此衍生的實作範例,請參閱AWS 用戶端身分驗證的 C99 程式庫實作
n = [NIST P-256 elliptic curve group order] G = [NIST P-256 elliptic curve base point] label = "AWS4-ECDSA-P256-SHA256" akid = [AWS access key ID as a UTF8 string] sk = [AWS secret access Key as a UTF8 Base64 string] input_key = "AWS4A" || sk count = 1 while (counter != 255) { context = akid || counter
// note: counter is one byte
key = KDF(input_key, label, context, 256) c = Oct2Int(key) if (c > n - 2) { counter++ } else { k = c + 1// private key
Q = k * G// public key
} } if (c < 255) { return [k, Q] } else { return FAILURE }
計算簽章
衍生簽署金鑰後,請計算要新增至請求的簽章。此程序會根據您使用的 siganture 版本而有所不同。
計算 SigV4 的簽章
-
呼叫雜湊函數,將上一次呼叫的結果做為金鑰,並將要簽署的字串做為資料。使用衍生的金鑰做為此操作的雜湊金鑰。結果是作為二進位值的簽章。
signature = hash(SigningKey,
string-to-sign
) -
將簽章的表示形式從二進位轉換為十六進位,使用小寫字元。
計算 SigV4a 的簽章
-
使用數位簽署演算法 (ECDSA P-256),簽署字串以簽署您在上一個步驟中建立的 。用於此簽章的金鑰是衍生自秘密存取金鑰的私有非對稱金鑰,如上所述。
signature = base16(
ECDSA-Sign
(k,string-to-sign
)) -
將簽章的表示形式從二進位轉換為十六進位,使用小寫字元。
將簽章新增至請求
將計算簽章新增至您的請求。
範例:授權標頭
SigV4
下列範例顯示使用 AWS SigV4 之DescribeInstances
動作的Authorization
標頭。為了便於閱讀,此範例使用換行符號進行格式化。在代碼中,這必須是一個連續字串。演算法和 Credential
之間沒有逗號。但是,必須使用逗號分隔其他元素。
Authorization: AWS4-HMAC-SHA256
Credential=AKIAIOSFODNN7EXAMPLE/20220830/us-east-1/ec2/aws4_request,
SignedHeaders=host;x-amz-date,
Signature=calculated-signature
SigV4a
下列範例顯示使用 AWS SigV4a 之CreateBucket
動作的授權標頭。為了便於閱讀,此範例使用換行符號進行格式化。在代碼中,這必須是一個連續字串。演算法和登入資料之間沒有逗號。但是,必須使用逗號分隔其他元素。
Authorization: AWS4-ECDSA-P256-SHA256
Credential=AKIAIOSFODNN7EXAMPLE/20220830/s3/aws4_request,
SignedHeaders=host;x-amz-date;x-amz-region-set,
Signature=calculated-signature
範例:查詢字串中包含身分驗證參數的請求
SigV4
下列範例顯示使用包含身分驗證資訊的 AWS SigV4 之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
SigV4a
下列範例顯示使用包含身分驗證資訊的 AWS SigV4a 之CreateBucket
動作的查詢。為了便於閱讀,此範例使用換行符號進行格式化,而不是 URL 編碼。在程式碼中,查詢字串必須是 URL 編碼的連續字串。
https://ec2.amazonaws.com/?
Action=CreateBucket&
Version=2016-11-15&
X-Amz-Algorithm=AWS4-ECDSA-P256-SHA256&
X-Amz-Credential=AKIAIOSFODNN7EXAMPLE/20220830/s3/aws4_request&
X-Amz-Region-Set=us-west-1&
X-Amz-Date=20220830T123600Z&
X-Amz-SignedHeaders=host;x-amz-date;x-amz-region-set&
X-Amz-Signature=calculated-signature