imchandan
imchandan

Reputation: 23

Azure Shared Access Signature - Signature did not match String to sign used was

I have a requirement to generate the SAS token for azure blob using the Javascript.

This is the code i have written after searching through google and documentation.

var CryptoJS = require("crypto-js/core")

var blobAccount = 'ACCOUNTNAME';
var blobContainer = 'CONTAINERNAME/PATH_TO_FILE';
var sasToken = '';
var storageAccountKey = 'KEY2';


// Calculate the expiration time
var currentDate = new Date();
var expiration = new Date(currentDate.getTime() + (100 * 365 * 24 * 60 * 60 * 1000));

var st = currentDate.toISOString().slice(0,19)+'Z';
var se = expiration.toISOString().slice(0,19)+'Z';
var sv = '2018-11-09';
var sp = 'r';
var sr = 'b';

var canonicalizedResource = "/"+blobAccount+"/"+blobContainer;
var stringToSign = sp+'\n'+st+'\n'+se+'\n'+canonicalizedResource+'\n'+sv+'\n'+sr+'\n'+'\n'+'\n'+'\n'+'\n'+'\n'+'\n'+'\n';
var signature = CryptoJS.HmacSHA256(stringToSign, CryptoJS.enc.Base64.parse(storageAccountKey)).toString(CryptoJS.enc.Base64);
sasToken = encodeURIComponent(signature)+"&st="+st.replaceAll(':','%3A')+"&se="+se.replaceAll(':','%3A')+"&sv=2018-11-09&sp=r&sr=b"

var url = "https://"+blobAccount+".blob.core.windows.net/"+blobContainer+"?"+"sig="+sasToken

console.log(sasToken);
console.log(url)

I'm able to generate the url but when used directly in browser i get the error

<Error>
<Code>AuthenticationFailed</Code>
<Message>Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature. RequestId:1145b24b-201e-005c-3b3b-86f4f3000000 Time:2023-05-14T08:10:23.2762870Z</Message>
<AuthenticationErrorDetail>Signature did not match. String to sign used was r 2023-05-14T08:09:57Z 2123-04-20T08:09:57Z /blob/ACCOUNTNAME/CONTAINERNAME/PATH_TO_FILE 2018-11-09 b </AuthenticationErrorDetail>
</Error>

I have tried lots of combinations to create stringToSign, i dont seem to know where i'm going wrong.I'm really hoping someone can help me solve this. I have masked ACCOUNTNAME,CONTAINERNAME,PATH_TO_FILE,KEY2 here but you can assume the values for it. My usecase is to use this code in a business rule in servicenow and use cryptoJS module as a script include. But that comes after this code starts generating the correct URL.

Upvotes: 0

Views: 632

Answers (2)

imchandan
imchandan

Reputation: 23

I was able to resolve this. After researching the web again for stringToSign i understood its format

String stringToSign= "rl\n"+ start +"\n" + expiry+ "\n"+ "/blob/"+accountName+"/CONTAINER/PATH_TO_FILE\n"+ "\n"+ "\n"+ "\n"+ azureApiVersion+"\n"+ "b\n"+"\n"+"\n"+"\n"+"\n"+"\n";

But the PATH_TO_FILE i use has a space which i was replacing with %20 before creating stringToSign. I removed that space to %20 conversion and it started working fine.

Upvotes: 0

Gaurav Mantri
Gaurav Mantri

Reputation: 136346

Please try by changing the following lines of code:

var sr = 'b';

var canonicalizedResource = "/"+blobAccount+"/"+blobContainer;

to

//this indicates that the signed resource is a blob container
var sr = 'c';

//need to prefix your canonicalized resource with service type i.e. blob.
var canonicalizedResource = "/blob/"+blobAccount+"/"+blobContainer;

Also change the following line of code:

sasToken = encodeURIComponent(signature)+"&st="+st.replaceAll(':','%3A')+"&se="+se.replaceAll(':','%3A')+"&sv=2018-11-09&sp=r&sr=b"

to

sasToken = encodeURIComponent(signature)+"&st="+st.replaceAll(':','%3A')+"&se="+se.replaceAll(':','%3A')+"&sv=2018-11-09&sp=r&sr=c"

Upvotes: 0

Related Questions