如何使用Signature v4

时间:2017-06-19 08:21:44

标签: amazon-web-services curl amazon-s3

我现在尝试了几天但却陷入了签名计算的困境。对于后台,我将EC2实例角色分配给实例,还需要使用MKS SSE(服务器端加密)在S3中存储数据。

所以,这是我现在使用的脚本:

#!/usr/bin/env bash
set -E
export TERM=xterm
#    
s3_region='eu-west-1'
s3_bucket='my-s3-file-bucket'
#
bkup_optn='hourly'
data_type='application/octet-stream'
bkup_path="/tmp/backups/${bkup_optn}"
bkup_file="$( ls -t ${bkup_path}|head -n1 )"
timestamp="$( LC_ALL=C date -u "+%Y-%m-%d %H:%M:%S" )"
#
appHost="$( hostname -f )"
thisApp="$( facter -p my_role )"
thisEnv="$( facter -p my_environment )"
upldUri="${thisEnv}/${appHost}/${bkup_optn}/${bkup_file}"

# This doesn't work on OS X
iso_timestamp=$(date -ud "${timestamp}" "+%Y%m%dT%H%M%SZ")
date_scope=$(date -ud "${timestamp}" "+%Y%m%d")
date_header=$(date -ud "${timestamp}" "+%a, %d %h %Y %T %Z")

## AWS instance role
awsMetaUri='http://169.254.169.254/latest/meta-data/iam/security-credentials/'
awsInstRole=$( curl -s ${awsMetaUri} )
awsAccessKey=$( curl -s ${awsMetaUri}${awsInstRole}|awk -F'"' '/AccessKeyId/ {print $4}' )
awsSecretKey=$( curl -s ${awsMetaUri}${awsInstRole}|grep SecretAccessKey|cut -d':' -f2|sed 's/[^0-9A-Za-z/+=]*//g' )
awsSecuToken=$( curl -s ${awsMetaUri}${awsInstRole}|sed -n '/Token/{p;}'|cut -f4 -d'"' )
signedHeader='date;host;x-amz-content-sha256;x-amz-date;x-amz-security-token;x-amz-server-side-encryption;x-amz-server-side-encryption-aws-kms-key-id'
echo -e "awsInstRole  => ${awsInstRole}\nawsAccessKey => ${awsAccessKey}\nawsSecretKey => ${awsSecretKey}"

payload_hash()
{
  local output=$(shasum -ba 256 "${bkup_path}/${bkup_file}")
  echo "${output%% *}"
}

canonical_request()
{
  echo "PUT"
  echo "/${upldUri}"
  echo ""
  echo "date:${date_header}"
  echo "host:${s3_bucket}.s3.amazonaws.com"
  echo "x-amz-security-token:${awsSecuToken}"
  echo "x-amz-content-sha256:$(payload_hash)"
  echo "x-amz-server-side-encryption:aws:kms"
  echo "x-amz-server-side-encryption-aws-kms-key-id:arn:aws:kms:eu-west-1:xxxxxxxx111:key/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx1432"
  echo "x-amz-date:${iso_timestamp}"
  echo ""
  echo "${signedHeader}"
  printf "$(payload_hash)"
}

canonical_request_hash() 
{
  local output=$(canonical_request | shasum -a 256)
  echo "${output%% *}"
}

string_to_sign()
{
  echo "AWS4-HMAC-SHA256"
  echo "${iso_timestamp}"
  echo "${date_scope}/${s3_region}/s3/aws4_request"
  echo "x-amz-security-token:${awsSecuToken}"
  echo "x-amz-server-side-encryption:aws:kms"
  echo "x-amz-server-side-encryption-aws-kms-key-id:arn:aws:kms:eu-west-1:xxxxxxxx111:key/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx1432"
  printf "$(canonical_request_hash)"
}

signature_key()
{
  local secret=$(printf "AWS4${awsSecretKey}" | hex_key)
  local date_key=$(printf ${date_scope} | hmac_sha256 "${secret}" | hex_key)
  local region_key=$(printf ${s3_region} | hmac_sha256 "${date_key}" | hex_key)
  local service_key=$(printf "s3" | hmac_sha256 "${region_key}" | hex_key)
  printf "aws4_request" | hmac_sha256 "${service_key}" | hex_key
}

hex_key() {
  xxd -p -c 256
}

hmac_sha256() {
  local hexkey=$1
  openssl dgst -binary -sha256 -mac HMAC -macopt hexkey:${hexkey}
}

signature() {
  string_to_sign | hmac_sha256 $(signature_key) | hex_key | sed "s/^.* //"
}

curl \
  -T "${bkup_path}/${bkup_file}" \
  -H "Authorization: AWS4-HMAC-SHA256 Credential=${awsAccessKey}/${date_scope}/${s3_region}/s3/aws4_request,SignedHeaders=${signedHeader},Signature=$(signature)" \
  -H "Date: ${date_header}" \
  -H "x-amz-date: ${iso_timestamp}" \
  -H "x-amz-security-token:${awsSecuToken}" \
  -H "x-amz-content-sha256: $(payload_hash)" \
  -H "x-amz-server-side-encryption:aws:kms" \
  -H "x-amz-server-side-encryption-aws-kms-key-id:arn:aws:kms:eu-west-1:xxxxxxxx111:key/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx1432" \
  "https://${s3_bucket}.s3.amazonaws.com/${upldUri}"

按照此文档编写: http://docs.aws.amazon.com/general/latest/gr/sigv4-create-canonical-request.html和Github中的示例脚本中的部分,我忘记了书签。在最初的颠簸之后,现在我不断收到这个错误:

<Error><Code>SignatureDoesNotMatch</Code><Message>The request signature we calculated does not match the signature you provided. Check your key and signing method.</Message><AWSAccessKeyId>XXXXXXXXXXXXXXX</AWSAccessKeyId><StringToSign>AWS4-HMAC-SHA256

我浏览了几个AWS文档,但我无法弄清楚原因。有人可以帮帮我吗?

-San

0 个答案:

没有答案