使用 AWS4 身份验证通过 bash 将文件上传到 s3?

jyc*_*753 7 bash amazon-s3

尝试将文件自动加载到 S3 时,我不断收到此错误:

我们计算的请求签名与您提供的签名不匹配。检查您的密钥和签名方法。

HMAC-SHA256s(){
 KEY="$1"
 DATA="$2"
 shift 2
 printf "$DATA" | openssl dgst -binary -sha256 -hmac "$KEY" | od -An -vtx1 | sed 's/[ \n]//g' | sed 'N;s/\n//'
}

HMAC-SHA256h(){
 KEY="$1"
 DATA="$2"
 shift 2
 printf "$DATA" | openssl dgst -binary -sha256 -mac HMAC -macopt "hexkey:$KEY" | od -An -vtx1 | sed 's/[ \n]//g' | sed 'N;s/\n//'
}


FILE_TO_UPLOAD=/var/www/cool/main.txt
BUCKET="temporaltestingstorage"
STARTS_WITH="Schiller/Zauberlehrling"

REQUEST_TIME=$(date +"%Y%m%dT%H%M%SZ")
REQUEST_REGION="eu-central-1"
REQUEST_SERVICE="s3"
REQUEST_DATE=$(printf "${REQUEST_TIME}" | cut -c 1-8)
AWS4SECRET="AWS4"$AWS_SECRET_KEY
ALGORITHM="AWS4-HMAC-SHA256"
EXPIRE="2015-01-01T00:00:00.000Z"
ACL="private"

POST_POLICY='{"expiration":"'$EXPIRE'","conditions": [{"bucket":"'$BUCKET'" },{"acl":"'$ACL'" },["starts-with", "$key", "'$STARTS_WITH'"],["eq", "$Content-Type", "application/octet-stream"],{"x-amz-credential":"'$AWS_ACCESS_KEY'/'$REQUEST_DATE'/'$REQUEST_REGION'/'$REQUEST_SERVICE'/aws4_request"},{"x-amz-algorithm":"'$ALGORITHM'"},{"x-amz-date":"'$REQUEST_TIME'"}]}'

UPLOAD_REQUEST=$(printf "$POST_POLICY" | openssl base64 )
UPLOAD_REQUEST=$(echo -en $UPLOAD_REQUEST |  sed "s/ //g")

SIGNATURE=$(HMAC-SHA256h $(HMAC-SHA256h $(HMAC-SHA256h $(HMAC-SHA256h $(HMAC-SHA256s $AWS4SECRET $REQUEST_DATE ) $REQUEST_REGION) $REQUEST_SERVICE) "aws4_request") $UPLOAD_REQUEST)

curl \
    --limit-rate 300k \
    --connect-timeout 120 \
  -F "key=$STARTS_WITH" \
  -F "acl=$ACL" \
  -F "Content-Type=application/octet-stream" \
  -F "x-amz-algorithm=$ALGORITHM" \
  -F "x-amz-credential=$AWS_ACCESS_KEY/$REQUEST_DATE/$REQUEST_REGION/$REQUEST_SERVICE/aws4_request" \
  -F "x-amz-date=$REQUEST_TIME" \
  -F "Policy=$UPLOAD_REQUEST" \
  -F "X-Amz-Signature=$SIGNATURE" \
  -F "file=@"$FILE_TO_UPLOAD http://$BUCKET.s3.amazonaws.com/
Run Code Online (Sandbox Code Playgroud)

我错过了什么吗?

谢谢

Ran*_*ein 3

我建议您在正确调试脚本之前更改脚本中的几件事:

  1. “双引号”包含空格/元字符的每个文字和每个扩展:"$var", "$(command "$var")", "${array[@]}", "a & b"。看

  2. 关于变量POST_POLICY:单引号(ie ')导致它们之间的所有内容都被bash 按字面意思理解。在您的脚本中,诸如"$EXPIRE", "$BUCKET",之类的表达式"$ACL"不会用单引号展开。如果要将 a 嵌入'到 a 中'...',请将其写为四个字符'\''printf '%s\n' 'It'\''s a blast!'

    检查您的脚本中其他地方是否存在此问题,并进行相应修改。

  3. 按照约定,环境变量 ( PATHEDITORSHELL...) 和内部 shell 变量 ( BASH_VERSIONRANDOM、 ...) 完全大写。所有其他变量名称都应小写。由于变量名称区分大小写,因此此约定可以避免意外覆盖环境变量和内部变量。

  4. echo有许多可移植性问题,并且永远不应该与选项标志一起使用。请printf改用:printf 'name: %s\n' "$name". 看

  5. 不是那么重要,但值得一提:不要在printf的格式字符串中使用变量(例如printf '%s' "$DATA"代替printf "$DATA")。