首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >SubtleCrypto在JavaScript中验证HMAC的错误结果

SubtleCrypto在JavaScript中验证HMAC的错误结果
EN

Stack Overflow用户
提问于 2022-05-20 08:13:53
回答 1查看 173关注 0票数 0

我正在尝试使用SubtleCrypto API验证HMAC签名。整个程序应该在Cloudflare中运行,我正在使用他们的wrangler工具在本地测试它。

到目前为止,这是我的代码,但是它生成错误的签名。

代码语言:javascript
复制
const message = "(query params from an url)";
const given_signature = "(extracted from the query params)";
const SECRET = "...";

const algorithm = { name: 'HMAC', hash: 'SHA-256' };
const encoder = new TextEncoder();

const key = await crypto.subtle.importKey(
    'raw',
    encoder.encode(SECRET),
    algorithm,
    false,
    ['sign', 'verify']
);

const signature = await crypto.subtle.sign(
    algorithm.name,
    key,
    encoder.encode(message)
);

const digest = btoa(String.fromCharCode(...new Uint8Array(signature)));
// The digest does not match the signature extracted from the query params

// If I, for example, want to verify the signature directly, the result is still false.
const verify = await crypto.subtle.verify(
    algorithm.name,
    key,
    encoder.encode(given_signature),
    encoder.encode(message)
);

如果我在在线HMAC测试工具中使用相同的秘密和消息,我将得到正确的结果,所以我确信我的代码中一定有一个错误。

我发现有趣的是,我的代码生成的签名比给定的签名要短得多(例如,3fn0mhrebHTJMhtOyvRP5nZIhogX/M1OKQ5GojniZTM=ddf9f49a1ade6c74c9321b4ecaf44fe67648868817fccd4e290e46a239e26533)。

有人知道我哪里出了问题吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-05-20 12:29:22

感谢这些有益的评论!简而言之,问题在于提供的签名被编码为HEX字符串,而生成的签名是base64 64编码的字符串。

为了保持整洁,下面是一个使用crypto.subtle.verify函数的工作版本:

代码语言:javascript
复制
const message = "(query params from an url w/o the hmac signature)";
const given_signature = "(the given hmac signature extracted from the query params)";
const SECRET = "(my secret key)";

const hexToBuffer = (hex: string) => {
  const matches = hex.match(/[\da-f]{2}/gi) ?? [];
  const typedArray = new Uint8Array(
    matches.map(function (h) {
      return parseInt(h, 16);
    })
  );
  return typedArray.buffer;
};

const algorithm = { name: "HMAC", hash: "SHA-256" };
const encoder = new TextEncoder();

const key = await crypto.subtle.importKey(
  "raw",
  encoder.encode(SECRET),
  algorithm,
  false,
  ["sign", "verify"]
);

const result: boolean = await crypto.subtle.verify(
  algorithm.name,
  key,
  hexToBuffer(given_signature),
  encoder.encode(message)
);
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72315615

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档