I am trying to upload the blob in a azure storage container using REST APIs(note:container is already created). But i am getting error as "status: 403, statusText: 'Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.'"
I have prepared the request and signed with decoded access keys, and converting the same in base64 format. but still getting error. I am sharing the typescript code, please help me to find where I am doing mistake.
import fetch from 'node-fetch';
import defaults  from  "../modules/defaults";
import { createHmac } from "crypto";
    async function uploadBlob(){
        
        let data = "sampletest";
        let dataLength = (data.length).toString()
        console.log("dataLength\n",dataLength)
        
       
        let accountKey = `account key looks like MSUUUMyhMSU..`;
        console.log("key\n",accountKey);
        let blob_type = "BlockBlob";
        let request_time = new Date().toUTCString();
        let api_version = "2015-02-21"
        try{
           
            let string_params = {
                'verb': 'PUT',
                'Content-Encoding': '',
                'Content-Language': '',
                'Content-Length': dataLength,
                'Content-MD5': '',
                'Content-Type': '',
                'Date': '',
                'If-Modified-Since': '',
                'If-Match': '',
                'If-None-Match': '',
                'If-Unmodified-Since': '',
                'Range': '',
                'CanonicalizedHeaders': 'x-ms-blob-type:' + blob_type + '\nx-ms-date:' + request_time + '\nx-ms-version:' + api_version,
                'CanonicalizedResource': '/' + "pcatest" +'/'+ "pca-al" + '/' + "newBlob"
            }
            
            let string_to_sign = (string_params['verb'] + '\n' 
                              + string_params['Content-Encoding'] + '\n'
                              + string_params['Content-Language'] + '\n'
                              + string_params['Content-Length'] + '\n'
                              + string_params['Content-MD5'] + '\n' 
                              + string_params['Content-Type'] + '\n' 
                              + string_params['Date'] + '\n' 
                              + string_params['If-Modified-Since'] + '\n'
                              + string_params['If-Match'] + '\n'
                              + string_params['If-None-Match'] + '\n'
                              + string_params['If-Unmodified-Since'] + '\n'
                              + string_params['Range'] + '\n'
                              + string_params['CanonicalizedHeaders']
                              + string_params['CanonicalizedResource'])
          
            console.log("reqHeaders \n",string_to_sign);
            let reqHeaderHash = computeHMACSHA256(string_to_sign,accountKey);
            
            console.log("==============rearheaderHash=============\n",reqHeaderHash);
            let signature = `SharedKey ${defaults.accountName}:${reqHeaderHash}`;
            console.log("==============signature=============\n",signature);
            const url = "https://test.blob.core.windows.net/testcontainer/newblob";
            console.log("url",url);
            const response = await fetch(url,{
                method:"PUT",
                body: data,
                headers : {
                    "x-ms-date" : request_time,
                    "x-ms-version" : api_version,
                    "Content-Length": dataLength,
                    "x-ms-blob-type": blob_type,
                    "Authorization" : signature
                }  
            });
            console.log("============response==============\n",response);
            }
            catch(err)
            {
                console.log("error",err);
            }
        
    }
    
function computeHMACSHA256(stringToSign: string, accountKey: string): string {
  const key = Buffer.from(accountKey, "base64")
    console.log("key\n",key);
    return createHmac("sha256", key)
        .update(stringToSign, "utf8")
        .digest("base64");
}
    uploadBlob();