使用AWS4 auth通过bash将文件上传到s3?

时间:2016-04-15 03:53:54

标签: 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/
我错过了什么吗?

由于

2 个答案:

答案 0 :(得分:2)

我建议您在脚本更改之前先修改一些内容:

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

  2. 关于变量"a & b":单引号(即POST_POLICY)会导致它们之间的所有内容都被bash视为字面上。在您的脚本中,'"$EXPIRE""$BUCKET"等表达式不会在单引号中展开。如果您想在"$ACL"中嵌入',请将其写为四个字符'...''\''

    检查脚本中的更多位置是否存在此问题,并相应地进行修改。

  3. 按照惯例,环境变量(printf '%s\n' 'It'\''s a blast!'PATHEDITOR,...)和内部shell变量(SHELLBASH_VERSION ,...)完全资本化。所有其他变量名称应为小写。以来 变量名称区分大小写,这种约定避免意外地覆盖环境和内部变量。

  4. RANDOM有许多可移植性问题,不应该与选项标志一起使用。请改为使用echoprintf。 参见

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

    < / LI>

答案 1 :(得分:1)

我会通过在文件顶部放置一个set -x来调试它,以便您可以看到所有命令输出。

我最近在我的bash脚本中使用过多或过少的引号都遭受了很多痛苦。我不是专家,但在我看来,你可能会在引文中包含一些变量。这可能会产生错误的摘要。

此外,由于您在openssl输出上进行了一些修改,因此您创建摘要的方式似乎有点容易出错。必须有一种方法可以避免我们使用openssl来创建Amazon指定的摘要。去偷看。

,在documentation 中,它们为您提供了一种测试正确创建签名的方法。我会尝试你的签名逻辑,这会缩小你对你做SHA256的方式的问题。

这里有gist和一些志同道合的人。看到一些过时的博客文章,这个要点似乎与文档不同,但我很欣赏他们对SHAing的简单看法。也许你应该在那里分享你的问题并要求他们更新要点。

对不起,这不是一个更好的答案,但是评论太长了。我希望它能得到更好的回答!一直有兴趣了解有关openssl的更多信息。