一句話:SigV4 不直接拿 secret key 簽,而是把它一層層揉進「日期→region→service→aws4_request」,做四次 HMAC 長出 Signing Key——一把只對那一天、那個 region、那個 service 有效的衍生金鑰。
kDate = HMAC-SHA256("AWS4" + SecretKey, "20130524") // 綁日期
kRegion = HMAC-SHA256(kDate, "us-east-1") // 綁 region
kService = HMAC-SHA256(kRegion, "s3") // 綁 service
kSigning = HMAC-SHA256(kService,"aws4_request") // ← Signing Key
每一層都拿上一層的輸出當 key、再對下一個字串做 HMAC。最後的 kSigning 才是拿去簽 String to Sign 的那把筆。
直接拿 secret key 簽也能動,但 AWS 刻意做成作用域受限的衍生金鑰,好處有二:
X-Amz-Expires 最多 7 天的底層原因(Signing Key 只推得出當日那把)。kDate 那一瞬被用到,效力被層層壓進 Signing Key、再壓進簽章。網址裡、傳輸中、server 比對時,都不會出現 secret key 本身。比喻:secret key 是保險箱裡的總印章,你捨不得天天拿出來蓋。於是你用它刻一顆「只有今天、只有台北分行、只有出納櫃檯能用」的臨時章(Signing Key),拿臨時章去蓋文件。臨時章掉了,小偷也只能在今天的台北出納櫃檯搞事,明天就作廢;總印章始終沒離開保險箱。
server 靠網址裡 X-Amz-Credential 的 access key ID 查出對應 secret key,再用一模一樣的四步長出同一把 Signing Key,重算簽章比對。兩邊各自推、結果相等——這就是 HMAC「key 不用傳、各算各的、比結果」的精神。