如何在没有加密库的情况下在 Node-red 上构建 Azure 存储的授权标头?

How to contruct an Authorization Header for Azure Storage on Node-red without crypto library?

提问人:lookpix3000 lxx 提问时间:11/18/2023 最后编辑:Tugaylookpix3000 lxx 更新时间:11/18/2023 访问量:21

问:

我正在尝试在 node-red 上使用他们的 API 连接到 azure 存储。 由于我的节点红色无法在其上安装任何东西,因此我尝试以其他方式创建并签名。在我构建了所需的标题和内容后,它显示:HMAC

<?xml version="1.0" encoding="utf-8"?><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:f280ad0a-501e-0011-5e83-197426000000
Time:2023-11-17T18:22:46.2298708Z</Message><AuthenticationErrorDetail>The MAC signature found in the HTTP request 'MzZlM2M0ZWQzYzdiYjM2NjVhNTQ4NzA0MDhhMjk2NzdkMjdiNjM3YjhlYzM5N2UzYTkxZmIzODkwZjAxNDNiOQ==' is not the same as any computed signature. Server used following string to sign: 'GET
x-ms-date:Fri, 17 Nov 2023 18:22:46 GMT
x-ms-version:2020-04-08
/litmusdev133/litmus
comp:list
restype:container'.</AuthenticationErrorDetail></Error>

我在 Node-red 上的整体流程Node-red Overall Flow

功能 1 :

function createBlobServiceSignature(storageAccount, storageKey, method, contentLength, contentType, date, resource) {
        // Parts of the string to sign
    const parts = [
        method.toUpperCase(),
        "",  // Content-Encoding
        "",  // Content-Language
        contentLength || "",  // Content-Length (empty string for zero)
        "",  // Content-MD5
        contentType || "",
        "",  // Date
        "",  // If-Modified-Since 
        "",  // If-Match
        "",  // If-None-Match
        "",  // If-Unmodified-Since
        "",  // Range
        canonicalizeHeaders({ "x-ms-date": date }),  // Canonicalized headers
        msVersion,
        resource,  // Canonicalized resource
        "comp:list",
        "restype:container"
    ];

    // Create the string to sign
    const stringToSign = parts.join('\n');
    msg.string = stringToSign;

    // Decode the storage key
    const key = Buffer.from(storageKey, 'base64');
    msg.secrectkey = key;

    return stringToSign;
    
}

function canonicalizeHeaders(headers) {
    // Sort headers and format them
    return Object.keys(headers)
        .sort()
        .map(name => `${name.toLowerCase().trim()}:${headers[name].trim()}`)
        .join('\n');
}

// Example usage
const storageAccount = 'litmusdev133';
const storageKey = 'Example';
const method = 'GET';
const contentType = '';
const date = new Date().toUTCString();
const resource = '/litmusdev133/'
const msVersion = "x-ms-version:2020-04-08"

const authorizationHeader = createBlobServiceSignature(storageAccount, storageKey, method, '', contentType, date, resource);

// Setting the output message
msg.payload = authorizationHeader;
msg.secrectkey = storageKey;
msg.payload = Buffer.from(msg.payload).toString('utf8');

return msg;

功能二:

// Example usage
const storageAccount = 'litmusdev133';
const storageKey = 'Example';
const method = 'GET';
const contentType = '';
const date = new Date().toUTCString();
const resource = '/litmusdev133/'
                            
const signature = msg.payload

msg.payload = 'SharedKey ' + storageAccount + ':' + signature;

return msg

功能 3 :

// Get the current date and time in UTC
var now = new Date();

// Convert UTC to GMT+8
var gmt8 = new Date(now.getTime())

// Convert to a string in a standard format
var gmt8String = gmt8.toUTCString();

authorization = msg.payload

msg.headers = {
    "x-ms-date" : gmt8String,
    "x-ms-version" :  "2020-04-08",
    "Authorization" : authorization
};

msg.reqheader = msg.headers;

return msg;

HMAC配置:HMAC

Base64 配置:Base 64

HTTP 配置:HTTP

我可以确保我的密钥和容器是正确的。 我尝试了python,它起作用了,所以我尝试将步骤复制到节点红色流,但我的身份验证失败了。

这是我引用的用于创建 node-red 流的 python 代码:

import requests
import hmac
import hashlib
import base64
from datetime import datetime, timezone

account_name = 'litmusdev133'
account_key = 'Example'
container_name = 'litmus'

url = f'https://{account_name}.blob.core.windows.net/{container_name}?restype=container&comp=list'
current_time = datetime.utcnow().strftime('%a, %d %b %Y %H:%M:%S GMT')
string_to_sign = f"GET\n\n\n\n\n\n\n\n\n\n\n\nx-ms-date:{current_time}\nx-ms-version:2020-08-04\n/{account_name}/{container_name}\ncomp:list\nrestype:container"
signature = base64.b64encode(hmac.new(base64.b64decode(account_key), string_to_sign.encode('utf-8'), hashlib.sha256).digest()).decode()
authorization_header = f"SharedKey {account_name}:{signature}"
headers = {
    'x-ms-date': current_time,
    'x-ms-version': '2020-08-04',
    'Authorization': authorization_header
}

response = requests.get(url, headers=headers)
print(response.text)

任何指导将不胜感激,谢谢

JavaScript Python 节点红 蕊试金石

评论

1赞 esqew 11/18/2023
我的节点红色无法在其上安装任何东西” 听起来这是您的实际问题,为什么不解决这个问题呢?试图推出自己的加密货币真的很疯狂

答: 暂无答案