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

使用WebCrypto API生成密钥对并签名时哈希缺失错误的解决方法

解决WebCrypto API ECDSA签名时"algorithm.hash is required"错误

问题出在调用sign方法时直接使用privateKey.algorithm作为算法参数——WebCrypto返回的ECDSA密钥算法对象里并不包含哈希算法配置,而ECDSA签名必须明确指定哈希算法才能完成数据摘要计算。

修正步骤

  1. 明确签名时的算法配置
    不要直接传递privateKey.algorithm,手动构造包含hash字段的算法对象,且哈希算法要和密钥生成时的配置保持一致。

  2. 修正后的代码
    先保留密钥生成函数(建议明确指定哈希算法,保持前后逻辑统一):

    const generateKeyPair = async function() {
        return crypto.subtle.generateKey(
            {
                name: "ECDSA",
                namedCurve: "P-384",
                hash: "SHA-512" // 提前指定哈希算法,与签名时保持一致
            },
            true,
            ["sign", "verify"]
        );
    }
    

    然后修改签名函数,手动构造符合要求的算法参数:

    const sign = async function(privateKey: CryptoKey, buffer: BufferSource) {
        const signAlgorithm = {
            name: privateKey.algorithm.name,
            namedCurve: privateKey.algorithm.namedCurve,
            hash: "SHA-512" // 必须与密钥生成时的哈希算法一致
        };
        return crypto.subtle.sign(signAlgorithm, privateKey, buffer);
    }
    

补充验签实现(匹配核心需求)

如果需要完成公钥验签的逻辑,同样要手动指定哈希算法:

const verify = async function(publicKey: CryptoKey, buffer: BufferSource, signature: ArrayBuffer) {
    const verifyAlgorithm = {
        name: publicKey.algorithm.name,
        namedCurve: publicKey.algorithm.namedCurve,
        hash: "SHA-512"
    };
    return crypto.subtle.verify(verifyAlgorithm, publicKey, signature, buffer);
}

测试用例验证

修正后的签名函数可以通过原有测试,也可以扩展验证完整的签名-验签流程:

import { describe, it, expect } from "vitest";
import { generateKeyPair, sign, verify } from "../../src";

describe("sign and verify", () => {
    it('signs data and verifies signature correctly', async () => {
        const { privateKey, publicKey } = await generateKeyPair();

        const data = { foo: 'bar' };
        const stringifiedData = JSON.stringify(data);
        const buffer = Buffer.from(stringifiedData);

        const signature = await sign(privateKey, buffer);
        await expect(signature).toBeTruthy();

        const isValid = await verify(publicKey, buffer, signature);
        expect(isValid).toBe(true);
    });
});

关键原因说明

WebCrypto的ECDSA密钥对象不会存储哈希算法配置,即使你在generateKey时指定了hash字段,返回的CryptoKey.algorithm也只包含name和namedCurve两个属性。因此调用sign/verify时必须手动补充hash参数,否则会触发ERR_MISSING_OPTION错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 15:15:26