Azure 文件共享 SAS 令牌签名未按预期生成,如何为文件对象生成签名以匹配门户中生成的签名?
Posted
技术标签:
【中文标题】Azure 文件共享 SAS 令牌签名未按预期生成,如何为文件对象生成签名以匹配门户中生成的签名?【英文标题】:Azure File share SAS token signature not generating as expected, How do one generate signature for file object to match the one generated in portal? 【发布时间】:2021-03-05 20:10:55 【问题描述】:我正在尝试以编程方式为 SAS 令牌创建一个签名,当用户选择几个选项时,该签名应该与 azure 门户中生成的签名相匹配。但是,文档非常混乱,并不能指导您实现操作所需的内容。我在 azure 文件共享中有一个文件,我想通过生成 SAS 令牌并对其进行签名来访问它。我可以通过在 Azure 门户中选择适当的选项并访问文件来轻松地做到这一点,但我想以编程方式完成确切的事情。我用 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 portal中为上述sas token选择的对应选项如下图所示
使用的密钥是key1,如下:
l1wxekiJj9IcTw350w5c1MtVfYVP3qcz3zdxzCCp+YVaXqs9faOJfl/Z07AoLDnsnyn+POGjxjcFy3EF9g/r9Q==
我尝试的是为以下选项(要签名的字符串)生成签名,该签名取自 azure 门户生成的 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 令牌以进行文件对象访问。
【问题讨论】:
【参考方案1】:如果要创建 sas 令牌来访问 Azure 文件服务资源,签名字符串应如下所示。更多详情请参考here
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;
【讨论】:
谢谢吉姆,我非常感谢你。我指的是“创建服务 sas”,但正确的文档是“创建帐户 sas”。非常感谢您帮助我。以上是关于Azure 文件共享 SAS 令牌签名未按预期生成,如何为文件对象生成签名以匹配门户中生成的签名?的主要内容,如果未能解决你的问题,请参考以下文章
如何为 Azure Blob 存储中的文件夹生成共享访问签名?
Microsoft 文档在以编程方式生成 SAS 令牌时出现问题。错误:“签名字段格式不正确”
Azure CDN URL使用令牌身份验证和Blob存储SAS重写规则
尝试使用 SAS 访问 Azure blob 时收到“签名不匹配。使用的签名字符串是...”