Java Azure文件共享SAS令牌签名未按预期生成,如何为文件对象生成签名以匹配在门户中生成的签名?

Java Azure文件共享SAS令牌签名未按预期生成,如何为文件对象生成签名以匹配在门户中生成的签名?,java,azure,azure-storage,signature,Java,Azure,Azure Storage,Signature,我试图以编程方式为SAS令牌创建一个签名,当用户选择几个选项时,该签名应与azure门户中生成的签名相匹配。但是,文档非常混乱,无法指导您实现操作所需的内容。我在azure文件共享中有一个文件,我想通过生成SAS令牌并对其签名来访问它。通过在Azure portal中选择适当的选项并访问该文件,我可以很容易地做到这一点,但我希望以编程的方式实现这一点。我尝试使用java,但结果SAS令牌签名不匹配。请帮帮我 下面是我通过Azure Portal生成的SAS令牌: ?sv=2019-12-12&a

我试图以编程方式为SAS令牌创建一个签名,当用户选择几个选项时,该签名应与azure门户中生成的签名相匹配。但是,文档非常混乱,无法指导您实现操作所需的内容。我在azure文件共享中有一个文件,我想通过生成SAS令牌并对其签名来访问它。通过在Azure portal中选择适当的选项并访问该文件,我可以很容易地做到这一点,但我希望以编程的方式实现这一点。我尝试使用java,但结果SAS令牌签名不匹配。请帮帮我

下面是我通过Azure Portal生成的SAS令牌:

?sv=2019-12-12&ss=f&srt=o&sp=r&se=2020-11-23T12:20:39Z&st=2020-11-23T04:20:39Z&spr=https&sig=XI%2FlSZSXp54XVwk2G%2F23j%2FjqsrojVqJoAonh6gdaAPk%3D
在azure portal中为上述sas令牌选择的相应选项如下所示,如下图所示

使用的键为key1,如下所示:

l1wxekiJj9IcTw350w5c1MtVfYVP3qcz3zdxzCCp+YVaXqs9faOJfl/Z07AoLDnsnyn+POGjxjcFy3EF9g/r9Q==
我尝试的是为以下选项(要签名的字符串)生成一个签名,该签名取自azure portal生成的SAS令牌,并使用上面的键1

sv=2019-12-12&ss=f&srt=o&sp=r&se=2020-11-23T12:20:39Z&st=2020-11-23T04:20:39Z&spr=https
下面是我的java代码,它为上面要签名的字符串生成签名

import org.apache.tomcat.util.codec.binary.Base64;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.net.URLEncoder;
public class GenerateSAS {
    public static void main(String[] args) throws Exception{
        Mac sha256_HMAC = null;
        String hash = null;
        String input="sv=2019-12-12&ss=f&srt=o&sp=r&se=2020-11-23T12:20:39Z&st=2020-11-23T04:20:39Z&spr=https";
        input=URLEncoder.encode(input, "UTF-8");
        String key="l1wxekiJj9IcTw350w5c1MtVfYVP3qcz3zdxzCCp+YVaXqs9faOJfl/Z07AoLDnsnyn+POGjxjcFy3EF9g/r9Q==";
        sha256_HMAC = Mac.getInstance("HmacSHA256");
        SecretKeySpec secret_key = new SecretKeySpec(key.getBytes(), "HmacSHA256");
        sha256_HMAC.init(secret_key);
        hash = new String(Base64.encodeBase64(sha256_HMAC.doFinal(input.getBytes("UTF-8"))));
        System.out.println(hash);
    }
上述代码生成的签名是
MK/uu+NlURscoX1dymzipRN/Jb4aXyVzfbIVBz8l02M=
,这与azure门户中生成的签名不同,后者是
XI%2FlSZSXp54XVwk2G%2F23j%2FjqsrojVqJoAonh6gdaAPk%3D


请帮助我正确生成签名,这将帮助我将其附加到SAS令牌以访问文件对象。

如果要创建SAS令牌以访问Azure文件服务资源,签名字符串应如下所示。有关详细信息,请参阅

比如说

 public static void createSasToken(){

    String accountName = "accountName";
    String key = "accountKey";
    String resourceUrl = "https://"+accountName+".file.core.windows.net/fileShare/fileName";
    /**
     * please note the date formate should be  ISO 8601 UTC formats 
     * for further information, please refer to https://docs.microsoft.com/en-us/rest/api/storageservices/formatting-datetime-values
    */
    String start = "startTime";
    String expiry = "expiry";
    String apiVersion = "2019-12-12";

    String stringToSign = accountName + "\n" +
                "r\n" +
                "f\n" +
                "o\n" +
                start + "\n" +
                expiry + "\n" +
                "\n" +
                "https\n" +
                apiVersion +"\n";

    String signature = getHMAC256(key, stringToSign);

    try{

        String sasToken = "sv=" + azureApiVersion +
            "&ss=f" +
            "&srt=o" +
            "&sp=r" +
            "&se=" +URLEncoder.encode(expiry, "UTF-8") +
            "&st=" + URLEncoder.encode(start, "UTF-8") +
            "&spr=https" +
            "&sig=" + URLEncoder.encode(signature, "UTF-8");

    System.out.println(resourceUrl+"?"+sasToken);

    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
    }
}

private static String getHMAC256(String accountKey, String signStr) {
    String signature = null;
    try {
        SecretKeySpec secretKey = new SecretKeySpec(Base64.getDecoder().decode(accountKey), "HmacSHA256");
        Mac sha256HMAC = Mac.getInstance("HmacSHA256");
        sha256HMAC.init(secretKey);
        signature = Base64.getEncoder().encodeToString(sha256HMAC.doFinal(signStr.getBytes("UTF-8")));
    } catch (Exception e) {
        e.printStackTrace();
    }
    return signature;
}

谢谢你,吉姆,我非常感谢你。我指的是“创建服务sas”,但正确的文档是“创建帐户sas”。非常感谢你帮助我。
 public static void createSasToken(){

    String accountName = "accountName";
    String key = "accountKey";
    String resourceUrl = "https://"+accountName+".file.core.windows.net/fileShare/fileName";
    /**
     * please note the date formate should be  ISO 8601 UTC formats 
     * for further information, please refer to https://docs.microsoft.com/en-us/rest/api/storageservices/formatting-datetime-values
    */
    String start = "startTime";
    String expiry = "expiry";
    String apiVersion = "2019-12-12";

    String stringToSign = accountName + "\n" +
                "r\n" +
                "f\n" +
                "o\n" +
                start + "\n" +
                expiry + "\n" +
                "\n" +
                "https\n" +
                apiVersion +"\n";

    String signature = getHMAC256(key, stringToSign);

    try{

        String sasToken = "sv=" + azureApiVersion +
            "&ss=f" +
            "&srt=o" +
            "&sp=r" +
            "&se=" +URLEncoder.encode(expiry, "UTF-8") +
            "&st=" + URLEncoder.encode(start, "UTF-8") +
            "&spr=https" +
            "&sig=" + URLEncoder.encode(signature, "UTF-8");

    System.out.println(resourceUrl+"?"+sasToken);

    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
    }
}

private static String getHMAC256(String accountKey, String signStr) {
    String signature = null;
    try {
        SecretKeySpec secretKey = new SecretKeySpec(Base64.getDecoder().decode(accountKey), "HmacSHA256");
        Mac sha256HMAC = Mac.getInstance("HmacSHA256");
        sha256HMAC.init(secretKey);
        signature = Base64.getEncoder().encodeToString(sha256HMAC.doFinal(signStr.getBytes("UTF-8")));
    } catch (Exception e) {
        e.printStackTrace();
    }
    return signature;
}