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

3b6akqbq  于 2021-07-08  发布在  Java
关注(0)|答案(1)|浏览(646)

我正在尝试以编程方式为sas令牌创建一个签名,当用户选择几个选项时,该签名应与azure门户中生成的签名相匹配。然而,文档是如此混乱,并不能指导您实现所需的行动。我在azure文件共享中有一个文件,我想通过生成sas令牌来访问它并对其签名。我可以通过在azureportal中选择适当的选项并访问该文件来轻松地做到这一点,但我希望以编程的方式完成确切的事情。我用java尝试了,但是得到的sas令牌签名不匹配。请帮帮我。
下面是我通过azure门户生成的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门户中为上述sas令牌选择的相应选项如下所示

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

l1wxekiJj9IcTw350w5c1MtVfYVP3qcz3zdxzCCp+YVaXqs9faOJfl/Z07AoLDnsnyn+POGjxjcFy3EF9g/r9Q==

我尝试的是为下面的选项(要签名的字符串)生成一个签名,该签名取自azure portal生成的sas令牌,并使用上面的key1。

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令牌文件对象访问。

aydmsdu9

aydmsdu91#

如果您想创建sas令牌来访问azure文件服务资源,签名字符串应该如下所示。详情请参阅此处

StringToSign = accountname + "\n" +  
    signedpermissions + "\n" +  
    signedservice + "\n" +  
    signedresourcetype + "\n" +  
    signedstart + "\n" +  
    signedexpiry + "\n" +  
    signedIP + "\n" +  
    signedProtocol + "\n" +  
    signedversion + "\n"

例如

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;
}

相关问题