0

您好,我尝试在 java 中的 azure 存储上为 blob 创建一个 SAS。我写了以下代码:

  public static String GSAS(String url, String signedstart, String signedexpiry) throws 
     Exception {

    String accountName = "taelearninguat2";
    String accountKey = "xxxx"; // Here I hide the passsword 

    String signedpermissions = "r";

    signedstart = "2020-02-18T08:49Z";
    signedexpiry = "2020-02-28T08:49Z";


    String canonicalizedResource = "/blob/" + accountName + "/resource/8a5dcc036edbba6a016ede49fec30000.jpg";

    String signedIP = "";
    String signedProtocol = "";
    String signedidentifier = "";
    String signedversion = "2015-04-05";
    String rscc = "";
    String responsecontent = "file; attachment";
    String rsce = "";
    String rscl = "";
    String rsct = "binary";

    String stringToSign =
            signedpermissions + "\n" +
                    signedstart + "\n" +
                    signedexpiry + "\n" +
                    canonicalizedResource + "\n" +
                    signedidentifier + "\n" +
                    signedIP + "\n" +
                    signedProtocol + "\n" +
                    signedversion + "\n" +
                    rscc + "\n" +
                    responsecontent + "\n" +
                    rsce + "\n" +
                    rscl + "\n" +
                    rsct;

   String sig = computeHmac256(stringToSign,Base64.getDecoder().decode(accountKey));

    StringBuffer param = new StringBuffer();
    param.append("?")
            .append("sv=").append(URLEncoder.encode(signedversion, "UTF-8")).append("&")
            .append("sr=").append(URLEncoder.encode("b", "UTF-8")).append("&")
            .append("sig=").append(URLEncoder.encode(sig, "UTF-8")).append("&")
            .append("st=").append(URLEncoder.encode(signedstart, "UTF-8")).append("&")
            .append("se=").append(URLEncoder.encode(signedexpiry, "UTF-8")).append("&")
            .append("sp=").append(URLEncoder.encode(signedpermissions, "UTF-8")).append("&")
            .append("rscd=").append(URLEncoder.encode(responsecontent, "UTF-8")).append("&")
            .append("rsct=").append(URLEncoder.encode(rsct, "UTF-8"));
    String sasURL = url + param.toString();
    return sasURL;
}





static String computeHmac256(String stringToSign, byte[] accountKey) throws Exception {
    try {
        /*
        We must get a new instance of the Mac calculator for each signature calculated because the instances are
        not threadsafe and there is some suggestion online that they may not even be safe for reuse, so we use a
        new one each time to be sure.
         */
        Mac hmacSha256 = Mac.getInstance("HmacSHA256");
        hmacSha256.init(new SecretKeySpec(accountKey, "HmacSHA256"));
        byte[] utf8Bytes = stringToSign.getBytes("UTF-8");
        return Base64.getEncoder().encodeToString(hmacSha256.doFinal(utf8Bytes));
    } catch (Exception e) {
        throw new Error(e);
    }
}

假设我有一张图片,网址是:https ://taelearninguat2.blob.core.chinacloudapi.cn/resource/8a5dcc036edbba6a016ede49fec30000.jpg

所以 stringToSign 是:

r 
2020-02-18T08:49Z 
2020-02-28T08:49Z 
/blob/taelearninguat2/resource/8a5dcc036edbba6a016ede49fec30000.jpg



2015-04-05

file; attachment


binary

SAS url : https://taelearninguat2.blob.core.chinacloudapi.cn/resource/8a5dcc036edbba6a016ede49fec30000.jpg?sv=2015-04-05&sr=b&sig=IbBspyUvIyOoxq7XRs7nQ3zHK%2BrlZzoen9jwSN%2B1Yfw%3D&st=2020-02-18T08%3A49Z&se=2020 -02-28T08%3A49Z&sp=r&rscd=文件%3B+附件&rsct=二进制

<AuthenticationErrorDetail>Signature did not match. String to sign used was r 2020-02-18T08:49Z 2020-02-28T08:49Z /blob/taelearninguat2/resource/8a5dcc036edbba6a016ede49fec30000.jpg 2015-04-05 file; attachment</AuthenticationErrorDetail>

新更新:更改时间参数:signedstart = 2019-11-27 signedexpiry = 2019-12-04 然后结果为:签名在指定时间范围内无效:开始 [2019 年 11 月 27 日星期三 00:00:00 GMT] - 到期 [格林威治标准时间 2019 年 12 月 4 日星期三 00:00:00] - 当前 [格林威治标准时间 2020 年 2 月 20 日星期四 14:45:57]

但是 signedstart = 2020-02-19 signedexpiry = 2020-02-25 仍然签名不匹配

4

1 回答 1

0

请尝试更改以下代码行:

byte[] shaSig = HMACSHA256(stringToSign, accountKey);

byte[] shaSig = HMACSHA256(stringToSign, Base64.getDecoder().decode(accountKey));

基本上,您的帐户密钥是一个 base64 编码的字符串,您需要先对其进行解码。

您还可以在此处查看有关 Azure SDK 如何进行签名的代码:https ://github.com/Azure/azure-sdk-for-java/blob/1e2982e008aead0453e2295d41df5352c603fd34/storage/data-plane/src/主/java/com/microsoft/azure/storage/blob/SharedKeyCredentials.java#L213

于 2020-02-19T14:34:51.900 回答