调用Azure File Storage REST API时SharedKey签名认证失败咨询
问题现象
调用Azure File Storage REST API拉取文件时,构造的共享密钥签名鉴权失败,返回AuthenticationFailed错误。所用存储账号密钥可在Microsoft Azure Storage Explorer中正常完成读写、下载操作,排除密钥本身有效性问题。
服务端返回错误
/*I have rewritten all accounts and keys to fake*/ <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:aea05260-xxxx-xxxx-xxxx-xxxx58000000 Time:2022-06-30T03:26:24.1626176Z</Message> <AuthenticationErrorDetail>The MAC signature found in the HTTP request 'ZmEyNjY0YmUwNWNjYmI2MmE1NTI2MDBjOGUyNTE2OTY0NmUzMjQ3NTU3Y2EwN2JhMmY3NmI5NmRiNDkxMzU2NA== ' is not the same as any computed signature. Server used following string to sign: 'GET 0 x-ms-date:Thu, 30 Jun 2022 03:24:00 GMT x-ms-version:2014-02-14 /testgetfilestorage/integration/testfolder/abc123.xml'.</AuthenticationErrorDetail> </Error>
Postman测试配置
/*I have rewritten all accounts and keys to fake*/ GET https://testgetfilestorage.file.core.windows.net/integration/testfolder/abc123.xml 请求头: x-ms-version:2014-02-14 x-ms-date:Thu, 30 Jun 2022 03:24:00 GMT Authorization:SharedKey testgetfilestorage:ZmEyNjY0YmUwNWNjYmI2MmE1NTI2MDBjOGUyNTE2OTY0NmUzMjQ3NTU3Y2EwN2JhMmY3NmI5NmRiNDkxMzU2NA==
当前使用的签名逻辑
/*I have rewritten all accounts and keys to fake*/ 签名规则:Signature=Base64(HMAC-SHA256(UTF8(StringToSign), Base64.decode(<your_azure_storage_account_shared_key>))) 使用参数: StringToSign = 'GET\n\n\n0\n\n\n\n\n\n\n\n\nx-ms-date:Thu, 30 Jun 2022 03:24:00 GMT\nx-ms-version:2014-02-14\n/testgetfilestorage/integration/testfolder/abc123.xml' 存储账号密钥 = 'TRE/abcabcabcabc90+YCabcabcabcabcabcabcabcabcabcabcabcabcabcR2NC7i5WREgBAjNivlhwGhwmZQ==' 签名生成步骤: 1. 代入参数到签名公式 2. 对密钥做Base64解码得到二进制密钥 3. 将HMAC-SHA256计算结果转为十六进制字符串fa2664be05ccbb62a552600c8e25169646e3247557ca07ba2f76b96db4913564 4. 对十六进制字符串做Base64编码得到最终签名ZmEyNjY0YmUwNWNjYmI2MmE1NTI2MDBjOGUyNTE2OTY0NmUzMjQ3NTU3Y2EwN2JhMmY3NmI5NmRiNDkxMzU2NA==
核心错误点
签名计算第3、4步编码逻辑完全错误:
- HMAC-SHA256算法输出的是32字节长度的原始二进制字节数组,错误地先将二进制哈希结果转为十六进制可读字符串,再对这个十六进制字符串做Base64编码,完全不符合Azure的签名计算规则。
正确签名计算流程
1. 校验待签名字符串:当前构造的StringToSign和服务端返回的待签串完全一致,换行符数量、字段顺序均正确,这部分无需修改 2. 将存储账号密钥做Base64解码,得到原始二进制密钥字节数组 3. 将StringToSign按UTF-8编码转为字节数组,用步骤2得到的二进制密钥计算HMAC-SHA256值,得到32字节的原始二进制哈希结果 4. 直接对步骤3输出的原始二进制哈希结果做Base64编码,得到的字符串就是合法的签名值,不需要做十六进制转换
额外校验项
- 所有字符串转字节的步骤必须使用UTF-8编码,禁止使用GBK、ASCII等其他编码
- 请求头中
x-ms-date的时间和实际发起请求的时间差不能超过15分钟,否则会触发请求过期错误 - Authorization头格式严格为
SharedKey <存储账号名>:<签名值>,冒号前后不要加多余空格 - 不要在请求中额外添加未写入StringToSign的x-ms-开头自定义头,否则会导致待签串不匹配
内容的提问来源于stack exchange,提问作者Jack
相关产品推荐
相关产品推荐

