

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

# 針對 AWS API 請求的 Signature 第 4 版簽署進行故障診斷
<a name="reference_sigv-troubleshooting"></a>

**重要**  
除非您使用 AWS SDKs或 CLI，否則您必須撰寫程式碼來計算在請求中提供身分驗證資訊的簽章。SigV4 簽章計算可能是一項複雜的任務，我們建議您盡可能使用 AWS SDKs或 CLI。

當您開發建立已簽署請求的程式碼時，您可能會`SignatureDoesNotMatch`從中收到 HTTP 403 AWS 服務。這些錯誤表示 HTTP 請求中的簽章值與 AWS 服務 計算的簽章 AWS 不相符。當許可不允許呼叫者發出請求時，將傳回 HTTP 401 `Unauthorized` 錯誤。

如有以下情形，API 請求可能傳回錯誤：
+ API 請求未簽署，且 API 請求使用 IAM 身分驗證。
+ 用於簽署請求的 IAM 憑證不正確或沒有調用 API 的許可。
+ 已簽署 API 要求的簽章與 AWS 服務計算的簽章不符。
+ API 請求標頭不正確。

**注意**  
在探索其他錯誤解決方案之前，將您的簽署通訊協定從 AWS Signature 第 2 版 (SigV2) 更新為 AWS Signature 第 4 版 (SigV4)。服務 (例如 Amazon S3) 和區域不再支援 SigV2 簽署。

**Topics**
+ [憑證錯誤](#signature-v4-troubleshooting-credential)
+ [正式請求與簽署字串錯誤](#signature-v4-troubleshooting-canonical-errors)
+ [憑證範圍錯誤](#signature-v4-troubleshooting-credential-scope)
+ [金鑰簽署錯誤](#signature-v4-troubleshooting-key-signing)

## 憑證錯誤
<a name="signature-v4-troubleshooting-credential"></a>

確保使用 SigV4 簽署 API 請求。如果 API 請求未簽署，則您有可能收到錯誤：`Missing Authentication Token`。[新增缺少的簽章](https://docs.aws.amazon.com/IAM/latest/UserGuide/create-signed-request.html#add-signature-to-request)並重新傳送請求。

驗證存取金鑰和私密金鑰的身分驗證憑證是正確的。如果存取金鑰錯誤，則您有可能收到錯誤：`Unauthorized`。確保用於簽署請求的實體有權發出請求。如需詳細資訊，請參閱[對拒絕存取錯誤訊息進行疑難排解](troubleshoot_access-denied.md)。

## 正式請求與簽署字串錯誤
<a name="signature-v4-troubleshooting-canonical-errors"></a>

如果您錯誤計算 [建立正式請求的雜湊](reference_sigv-create-signed-request.md#create-canonical-request-hash) 或 [建立要簽署的字串](reference_sigv-create-signed-request.md#create-string-to-sign) 中正式請求，則該服務執行的簽章驗證步驟便會失敗，並顯示錯誤訊息：

```
The request signature we calculated does not match the signature you provided
```

當 AWS 服務收到已簽署的請求時，它會重新計算簽章。如果值之間有差異，則簽名不匹配。使用錯誤訊息中的值，比對正式請求和字串以及您的已簽署請求。若有任何差異，請修改簽署程序。

**注意**  
您也可以驗證您未透過可修改標頭或請求的代理傳送請求。

**Example 正式請求範例**  

```
GET                                                      -------- HTTP method
/                                                        -------- Path. For API stage endpoint, it should be /{stage-name}/{resource-path}
                                                         -------- Query string key-value pair. Leave it blank if the request doesn't have a query string.
content-type:application/json                            -------- Header key-value pair. One header per line.
host:0123456789.execute-api.us-east-1.amazonaws.com      -------- Host and x-amz-date are required headers for all signed requests.                       
x-amz-date:20220806T024003Z                              

content-type;host;x-amz-date                             -------- A list of signed headers
d167e99c53f15b0c105101d468ae35a3dc9187839ca081095e340f3649a04501        -------- Hash of the payload
```

要驗證私密金鑰是否與存取金鑰 ID 相符，可以使用已知有效的實作來測試它們。例如，使用 AWS SDK 或 AWS CLI 向 提出請求 AWS。

### API 請求標頭
<a name="signature-v4-troubleshooting-credential-header"></a>

當授權標頭為空、憑證金鑰或簽章遺失或不正確、標頭不是以演算法名稱開頭，或金鑰值對不包含等號時，您會收到下列其中一個錯誤：
+ 授權標頭不能為空白。
+ 授權標頭需要 'Credential' 參數。
+ 授權標頭需要 'Signature' 參數。
+ 簽章在授權標頭中包含無效的 key=value 對 (缺少等號)。

確保您在 [計算簽章](reference_sigv-create-signed-request.md#calculate-signature) 中新增的 SigV4 授權標頭包含正確的憑證金鑰，且還包含使用 HTTP Date 或 `x-amz-date` 標頭的請求日期。

如果您收到 IncompleteSignatureException 錯誤且簽章的建構正確，您可以透過計算用戶端請求中授權標頭的 SHA-256 雜湊和 B64 編碼 AWS 服務 ，來驗證授權標頭未在傳輸到 時遭到修改。

1. 取得您在請求中傳送的[授權標頭](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_sigv-authentication-methods.html)。授權標頭看起來類似下列範例：

   ```
   Authorization: AWS4-HMAC-SHA256 
   Credential=AKIAIOSFODNN7EXAMPLE/20130524/us-east-1/s3/aws4_request, 
   SignedHeaders=host;range;x-amz-date,
   Signature=example-generated-signature
   ```

1. 計算授權標頭的 SHA-256 雜湊。

   ```
   hashSHA256(rawAuthorizationHeader) = hashedAuthorizationHeader
   ```

1. 將雜湊授權標頭編碼為 Base64 格式。

   ```
   base64(hashedAuthorizationHeader) = encodedHashedAuthorizationHeader
   ```

1. 將剛計算的雜湊和編碼字串與錯誤訊息中收到的字串進行比較。錯誤訊息應類似於如下範例：

   ```
   com.amazon.coral.service#IncompleteSignatureException: 
   The signature contains an in-valid key=value pair (missing equal-sign) 
   in Authorization header (hashed with SHA-256 and encoded with Base64): 
   '9c574f83b4b950926da4a99c2b43418b3db8d97d571b5e18dd0e4f3c3ed1ed2c'.
   ```
+ 如果兩個雜湊不同，授權標頭的某些部分會在傳輸中變更。此變更可能是由於您的網路或用戶端處理常式連接了已簽章的標頭，或以某種方式變更授權標頭。
+ 如果兩個雜湊相符，您在請求中傳送的授權標頭會符合 AWS 收到的內容。檢閱收到的錯誤訊息，以判斷問題是否是因為憑證或簽章不正確所致。此頁面的其他區段會涵蓋這些錯誤。

## 憑證範圍錯誤
<a name="signature-v4-troubleshooting-credential-scope"></a>

您在 [建立要簽署的字串](reference_sigv-create-signed-request.md#create-string-to-sign) 中建立的憑證範圍會將簽章限制在特定日期、區域和服務。此字串的格式如下所示：

```
YYYYMMDD/region/service/aws4_request
```

**注意**  
如果您使用的是 SigV4a，區域不包含在憑證範圍之中。

**Date**  
如果憑證範圍未指定與 x-amz-date 標頭相同的日期，則簽名驗證步驟會失敗，並顯示下列錯誤訊息：

```
Date in Credential scope does not match YYYYMMDD from ISO-8601 version of date from HTTP
```

如果請求指定未來的時間，則簽章驗證步驟會失敗，並顯示下列錯誤訊息：

```
Signature not yet current: date is still later than date
```

如果請求已過期，簽章驗證步驟會失敗，並顯示下列錯誤訊息：

```
Signature expired: date is now earlier than date
```

**區域**  
如果憑證範圍未指定與請求相同的區域，則簽名驗證步驟會失敗，並顯示下列錯誤訊息：

```
Credential should be scoped to a valid Region, not region-code
```

**服務**  
如果憑證範圍未指定與 host 標頭相同的服務，則簽名驗證步驟會失敗，並顯示下列錯誤訊息：

```
Credential should be scoped to correct service: 'service'
```

**終止字串**  
如果憑證範圍沒有以 aws4\$1request 結尾，則簽名驗證步驟會失敗，並顯示下列錯誤訊息：

```
Credential should be scoped with a valid terminator: 'aws4_request'
```

## 金鑰簽署錯誤
<a name="signature-v4-troubleshooting-key-signing"></a>

簽署金鑰衍生不正確或不當使用密碼編譯而造成的錯誤，較難進行故障診斷。確認正式字串和登入字串正確無誤之後，您也可以檢查下列其中一個問題：
+ 私密存取金鑰與您指定的存取金鑰 ID 不符。
+ 您的金鑰衍生程式碼發生問題。

要驗證私密金鑰是否與存取金鑰 ID 相符，可以使用已知有效的實作來測試它們。例如，使用 AWS SDK 或 AWS CLI 向 提出請求 AWS。如需取得範例，請參閱「[請求簽章範例](reference_sigv-examples.md)」。