简体   繁体   中英

HMAC SHA-256 for a signed AWS request

EDIT: The issue is that I'm using hex encoded strings as the keys and I should be using raw bytes. How can I get the raw bytes out of the openssl command?

--- Original question ---

I'm attempting to follow the instructions for creating a signed iam request found here: https://docs.aws.amazon.com/general/latest/gr/sigv4-calculate-signature.html .

It basically says to produce the signing key and signature you follow these steps:

signing key = HMAC(HMAC(HMAC(HMAC("AWS4wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY","20150830"),"us-east-1"),"iam"),"aws4_request")
signature = HexEncode(HMAC(signing key, "AWS4-HMAC-SHA256\n20150830T123600Z\n20150830/us-east-1/iam/aws4_request\nf536975d06c0309214f805bb90ccff089219ecd68b2577efef23edd43b7e1a59"))

I've created the following shell script as a test:

#!/usr/bin/env bash
set -euo pipefail

stringToSign="AWS4-HMAC-SHA256\n20150830T123600Z\n20150830/us-east-1/iam/aws4_request\nf536975d06c0309214f805bb90ccff089219ecd68b2577efef23edd43b7e1a59"

dateKey=$(echo -n "20150830" | openssl dgst -sha256 -hmac "AWS4wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY")
regionKey=$(echo -n "us-east-1" | openssl dgst -sha256 -hmac "$dateKey")
serviceKey=$(echo -n "iam" | openssl dgst -sha256 -hmac "$regionKey")
signingKey=$(echo -n "aws4_request" | openssl dgst -sha256 -hmac "$serviceKey")

echo "signing key: $signingKey"

signature=$(echo -n "$stringToSign" | openssl dgst -sha256 -hmac "$signingKey")

echo "signature: $signature"

The output is:

signing key: 8c028f7953b7f2b9fa6d2e816f7b15675dc2329c139e293b383759c5ba8af679
signature: 9fd29d6aaac30d0747da90c23a4b883a8bc02b439f35df255fa2f93f6c99f46f

dateKey is 45fb073b035485bb42f64d8d242984f3431d02e31c35ba4b661d31bbec45378d

However the document linked above says that it should be:

signing key: c4afb1cc5771d871763a393e44b703571b55cc28424d1a5e86da6ed3c154a4b9
signature: 5d672d79c15b13162d9279b0855cfba6789a8edb4c82c400e06b5924a6f2b5d7

How can I produce the correct key and signature?

EDIT -- openssl version:

$ openssl version -a
LibreSSL 2.6.5
built on: date not available
platform: information not available
options:  bn(64,64) rc4(16x,int) des(idx,cisc,16,int) blowfish(idx)
compiler: information not available
OPENSSLDIR: "/private/etc/ssl"

How can I get the raw bytes out of the openssl command?

Use -binary option. From manpage for openssl dgst :

openssl dgst [-cd] [-binary] [-digest] [-hex] [-hmac key] ...

     -binary
             Output the digest or signature in binary form.

To get the correct signature, I also had to replace the \n characters in the string to sign with actual newline characters.


Working script:

#!/usr/bin/env bash
set -euo pipefail

stringToSign="AWS4-HMAC-SHA256
20150830T123600Z
20150830/us-east-1/iam/aws4_request
f536975d06c0309214f805bb90ccff089219ecd68b2577efef23edd43b7e1a59"

dateKey=$(echo -n "20150830" | openssl dgst -sha256 -binary -hmac "AWS4wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY")
regionKey=$(echo -n "us-east-1" | openssl dgst -sha256 -binary -hmac "$dateKey")
serviceKey=$(echo -n "iam" | openssl dgst -sha256 -binary -hmac "$regionKey")
signingKey=$(echo -n "aws4_request" | openssl dgst -sha256 -binary -hmac "$serviceKey")
signature=$(echo -n "$stringToSign" | openssl dgst -sha256 -hmac "$signingKey")
echo "signature: $signature"
# signature: 5d672d79c15b13162d9279b0855cfba6789a8edb4c82c400e06b5924a6f2b5d7

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM