You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用JavaScript Crypto Subtle签名:需签编码消息还是其哈希值?

使用Web Crypto Subtle API进行消息签名:直接传编码消息还是哈希值?

问题背景

在使用浏览器内置的JavaScript Crypto Subtle API进行消息签名时,我们应当签名编码消息的哈希值,还是编码消息本身?

根据密码学领域的共识:

如果签名前不对数据进行哈希,就无法拥有统一的签名算法,因为只能对特定大小以内的消息签名,消息过大时仍需哈希,这并非签名方案的良好实践。更重要的是,部分签名方案(如RSA)在不哈希数据时易被伪造。为保证签名安全性不受消息大小影响,通常采用哈希后签名的范式,即先对明文消息哈希,再执行签名操作,这样算法可兼容任意大小的消息。

但查看MDN官方示例代码时发现,示例直接将编码后的消息传入sign函数:

function getMessageEncoding() {
  const messageBox = document.querySelector(".ecdsa #message");
  let message = messageBox.value;
  let enc = new TextEncoder();
  return enc.encode(message);
}

let encoded = getMessageEncoding();
let signature = await window.crypto.subtle.sign(
  {
    name: "ECDSA",
    hash: { name: "SHA-384" },
  },
  privateKey,
  encoded
);

示例仅在算法参数中指定了hash: { name: "SHA-384" },却直接签名编码消息而非其哈希值。这让人产生疑问:示例的做法是否有误?sign函数是否会自动对编码消息进行哈希后再签名?是否无需手动执行哈希操作?

解答

MDN示例的做法完全正确,无需手动哈希消息。

SubtleCrypto的sign函数在指定了hash参数的情况下,会自动完成「哈希消息→签名哈希值」的完整流程,开发者只需要传入编码后的原始消息即可,原因如下:

  • 对于ECDSA、RSA-PSS这类标准签名算法,「先哈希再签名」是算法本身要求的安全流程,API将这一步封装起来,既符合密码学最佳实践,也避免了开发者手动哈希时可能出现的错误(比如哈希算法不匹配、编码错误等)。
  • 这种设计完全契合哈希后签名的范式:API自动处理任意大小的消息哈希,保证签名算法对消息大小的兼容性,同时规避了未哈希签名带来的伪造风险。

需要注意:如果手动对消息哈希后再传入sign函数,会导致双重哈希,最终签名的是「消息哈希的哈希值」,这不符合标准签名流程,会导致后续验证签名失败。


内容的提问来源于stack exchange,提问作者sudoExclamationExclamation

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 08:43:30