Reputation: 137
I'm having some problems generating SAS token to download the file of Azure Storage. The following produces a URI that does not work. The error message I get back is Signature did not match
, and I'm uncertain why.
Has anyone generated SAS tokens, and got the signature to match manually?
static void Main(string[] args)
{
var sas = generateSAS
(
key, // Azure portal very secret ^-^
keyName, // Azure portal, example: key1
resourceUri, // example: https://myaccount.blob.core.windows.net/emails/email.pdf
resourcePath // example: /blob/myaccount/emails/email.pdf
);
}
private static string generateSAS(string key, string keyName, string uri, string path)
{
var permissions = "r";
var startTime = DateTime.UtcNow;
var endTime = DateTime.UtcNow.AddSeconds(60 * 2);
var canonicalizedresource = path;
var signedidentifier = keyName;
var signedversion = "2012-02-12";
var stringToSign = permissions + "\n" +
startTime.ToUniversalTime().ToString("u").Replace(" ", "T") + "\n" +
endTime.ToUniversalTime().ToString("u").Replace(" ", "T") + "\n" +
canonicalizedresource + "\n" +
signedidentifier + "\n" +
signedversion;
HMACSHA256 hmac = new HMACSHA256(Encoding.UTF8.GetBytes(key));
var signature = Convert.ToBase64String(hmac.ComputeHash(Encoding.UTF8.GetBytes(stringToSign)));
return string.Format(CultureInfo.InvariantCulture, "{0}?sp={1}&st={2}&se={3}&spr={4}&sv={5}&sr={6}&si={7}&sig={8}",
uri,
permissions,
startTime.ToUniversalTime().ToString("u").Replace(" ", "T"),
endTime.ToUniversalTime().ToString("u").Replace(" ", "T"),
"https",
signedversion,
"b",
keyName,
HttpUtility.UrlEncode(signature));
}
Upvotes: 0
Views: 537
Reputation: 29940
Please try the code below, it generates a valid sas token for me:
private static string generateSAS(string resourceUri, string account_name, string key)
{
var accountName = account_name;
var accountKey = key;
var start = DateTime.UtcNow.AddHours(-2).ToString("yyyy-MM-ddTHH:mm:ssZ");
var end = DateTime.UtcNow.AddHours(2).ToString("yyyy-MM-ddTHH:mm:ssZ");
var permission = "rwdlac";
var serviceType = "b";
var resourceTypes = "sco";
var protocol = "https";
var serviceVersion = "2019-02-02";
//here is the difference from your code.
var stringToSign = string.Format("{0}\n{1}\n{2}\n{3}\n{4}\n{5}\n{6}\n{7}\n{8}\n",accountName, permission,serviceType,resourceTypes,start,end,"",protocol,serviceVersion);
HMACSHA256 hmac = new HMACSHA256(Convert.FromBase64String(accountKey));
string signature = Convert.ToBase64String(hmac.ComputeHash(Encoding.UTF8.GetBytes(stringToSign)));
var sasToken = string.Format("?sv={0}&ss={1}&srt={2}&sp={3}&se={4}&st={5}&spr={6}&sig={7}", serviceVersion,
serviceType, resourceTypes, permission, end, start, protocol, HttpUtility.UrlEncode(signature));
var urlToListTables = resourceUri + sasToken;
return urlToListTables;
}
Upvotes: 1
Reputation: 136136
More than likely the issue is with the following line of code:
HMACSHA256 hmac = new HMACSHA256(Encoding.UTF8.GetBytes(key));
Please change it to:
HMACSHA256 hmac = new HMACSHA256(Convert.FromBase64String(key));
Upvotes: 0