替换 echo -n code>。第二个是用openssl上的 -binary 选项替换 sed magic。 比较原文: signature = $(echo -n$ string_to_sign| openssl dgst -sha256 -mac HMAC -macopthexkey:$ decoded_hex_key-binary | sed's /^.*= //'| base64 -w0) 固定: signature = $(printf$ string_to_sign| openssl dgst - sha256 -mac HMAC -macopthexkey:$ decoded_hex_key-binary | base64 -w0) 因为 echo -n 不会将 \\\ 转换为实际的换行符。 需要改变 -binary ,因为即使你剥离了坏的部分,openssl仍然输出ascii-encoded-十六进制,不是二进制。所以在它被传递给 base64 后,结果是十六进制表示的b64编码版本,而不是原始值。 I am attempting to use the Azure blob storage service from a bash script using the REST API. I know it is possible to accomplish this using various other tools or languages, however I'd like to do it as a bash script.The script below is an attempt to list the blobs in an Azure storage container.This script results in an authentication error. The signing string and headers look correct based on the REST API (reference) documentation. I suspect the problem may be in juggling the various parts of the signing process.Has anyone successfully used bash and curl to access cloud storage resources like Azure or other providers?#!/bin/bash# List the blobs in an Azure storage container.echo "usage: ${0##*/} <storage-account-name> <container-name> <access-key>"storage_account="$1"container_name="$2"access_key="$3"blob_store_url="blob.core.windows.net"authorization="SharedKey"request_method="GET"request_date=$(TZ=GMT date "+%a, %d %h %Y %H:%M:%S %Z")storage_service_version="2011-08-18"# HTTP Request headersx_ms_date_h="x-ms-date:$request_date"x_ms_version_h="x-ms-version:$storage_service_version"# Build the signature stringcanonicalized_headers="${x_ms_date_h}\n${x_ms_version_h}"canonicalized_resource="/${storage_account}/${container_name}"string_to_sign="${request_method}\n\n\n\n\n\n\n\n\n\n\n\n${canonicalized_headers}\n${canonicalized_resource}\ncomp:list\nrestype:container"# Decode the Base64 encoded access key, convert to Hex.decoded_hex_key="$(echo -n $access_key | base64 -d -w0 | xxd -p -c256)"# Create the HMAC signature for the Authorization headersignature=$(echo -n "$string_to_sign" | openssl dgst -sha256 -mac HMAC -macopt "hexkey:$decoded_hex_key" | sed 's/^.*= //' | base64 -w0)authorization_header="Authorization: $authorization $storage_account:$signature"curl \ -H "$x_ms_date_h" \ -H "$x_ms_version_h" \ -H "$authorization_header" \ "https://${storage_account}.${blob_store_url}/${container_name}?restype=container&comp=list"Update - The storage service error and the corresponding signing string that the script generated.Following is what the storage service returns for the AuthenticationFailed error.<?xml version="1.0" encoding="utf-8"?><Error> <Code>AuthenticationFailed</Code> <Message>Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.RequestId:27e6337e-52f3-4e85-98c7-2fabaacd9ebcTime:2013-11-21T22:10:11.7029042Z</Message> <AuthenticationErrorDetail>The MAC signature found in the HTTP request'OGYxYjk1MTFkYmNkMCgzN2YzODQwNzcyNiIyYTQxZDg0OWFjNGJiZDlmNWY5YzM1ZWQzMWViMGFjYTAyZDY4NAo='is not the same as any computed signature. Server used following string to sign:'GETx-ms-date:Thu, 21 Nov 2013 22:10:11 GMTx-ms-version:2011-08-18/storage_account_name/storage_containercomp:listrestype:container' </AuthenticationErrorDetail></Error>Next is the string_to_sign that the script generates.GET\n\n\n\n\n\n\n\n\n\n\n\nx-ms-date:Thu, 21 Nov 2013 22:10:11 GMT\nx-ms-version:2011-08-18\n/storage_account_name/storage_container\ncomp:list\nrestype:container 解决方案 I was able to get it working.There were two things wrong with this code, the first, as Patrick Park noted, was replacing the echo -n with printf. The second was replacing the sed magic with the -binary option on openssl.Compare the original:signature=$(echo -n "$string_to_sign" | openssl dgst -sha256 -mac HMAC -macopt "hexkey:$decoded_hex_key" -binary | sed 's/^.*= //' | base64 -w0)with the fixed:signature=$(printf "$string_to_sign" | openssl dgst -sha256 -mac HMAC -macopt "hexkey:$decoded_hex_key" -binary | base64 -w0)The echo change is needed because echo -n will not convert the \n into actual newlines.The -binary change is needed because even though you are stripping off the bad part, openssl was still outputting the signature in ascii-encoded-hex, not in binary. So after it was passed to base64, the result was the b64 encoded version of the hex representation, instead of the raw value. 这篇关于使用bash访问Azure blob存储,curl的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 上岸,阿里云! 07-26 02:12