Node.js与C#的HMAC-SHA512等效代码适配问题:Azure验证失败
问题根源及修复方案
你的Node.js代码无法通过Azure验证,核心是两个关键差异导致签名计算不匹配:
- 过期时间字符串格式不一致:C#使用
"O"格式(ISO 8601往返格式)输出7位小数的秒数(如2024-05-20T12:34:56.1230000Z),而Node.js的toJSON()仅输出3位小数(如2024-05-20T12:34:56.123Z),导致待签名的原始数据不同。 - 过期时间的时区计算偏差:C#基于UTC计算过期时间(
DateTime.UtcNow),而你的Node.js代码依赖本地时区计算(setDate),可能导致UTC时间值不一致。
修复后的Node.js代码
const { createHmac } = require('crypto'); const id = 'integration'; const key = 'SECRET_KEY'; // 基于UTC时间戳计算10天后的过期时间 const expiry = new Date(Date.now() + 10 * 24 * 60 * 60 * 1000); // 将日期格式化为C# "O"格式(带7位小数秒的UTC ISO字符串) function formatToRoundTripISO(date) { return date.toISOString().replace(/(\.\d{3})Z$/, '$10000Z'); } const formattedExpiry = formatToRoundTripISO(expiry); // 构造待签名的原始数据 const dataToSign = `${id}\n${formattedExpiry}`; // 计算HMAC-SHA512签名 const signature = createHmac('sha512', key) .update(dataToSign, 'utf8') .digest('base64'); // 生成最终的共享访问签名 const encodedToken = `SharedAccessSignature uid=${id}&ex=${formattedExpiry}&sn=${signature}`; console.log(encodedToken);
关键修复说明
- 统一时间格式:通过
formatToRoundTripISO函数将Node.js默认的3位小数秒扩展为7位,完全匹配C#的输出格式。 - UTC时间计算:使用
Date.now()(基于UTC的时间戳)计算过期时间,确保与C#的UtcNow行为一致,避免时区偏差。 - 对齐编码逻辑:直接传递UTF-8编码的字符串给
update方法,与C#的Encoding.UTF8.GetBytes行为一致。
修改后,Node.js生成的签名将与C#版本完全一致,可通过Azure验证。
内容的提问来源于stack exchange,提问作者Shanon Jackson
相关产品推荐
相关产品推荐

