可直接用 web crypto api 在前端离线实现 ecdsa 签名与验签:生成 p-256 密钥对,私钥不可导出,公钥导出为 spki;签名时用 textencoder 编码原文后调用 sign(),验签时导入公钥并调用 verify(),全程不联网、不依赖后端。

直接用 Web Crypto API 实现 ECDSA 离线电子签名与防篡改校验,不依赖后端、不联网也能完成整套流程。核心在于:前端生成密钥对、用私钥签名、用公钥验签,全程在用户设备本地执行。
ECDSA 密钥对生成与安全存储
ECDSA 使用椭圆曲线(如 P-256)实现高安全性与小体积密钥,适合前端运行。密钥必须严格区分用途,并避免明文暴露:
- 调用
window.crypto.subtle.generateKey({ name: "ECDSA", namedCurve: "P-256", hash: { name: "SHA-256" } }, true, ["sign", "verify"])生成密钥对 - 私钥设为
extractable: false(默认值),确保无法导出为原始字节,防止被恶意脚本窃取 - 公钥可导出为 SPKI 格式(
exportKey("spki", publicKey)),用于后续分发或存档 - 若需持久化,将公钥存入 localStorage 或 IndexedDB;私钥不保存——每次签名前由用户主动触发生成(推荐)或使用 Credential Management API 安全托管
离线数据签名:只在浏览器内完成
签名过程不上传原始数据,也不依赖服务端参与,真正“离线”:
- 用
TextEncoder将待签字符串转为Uint8Array(例如:new TextEncoder().encode("合同金额:¥12000.00;签署日期:2026-04-28")) - 调用
subtle.sign({ name: "ECDSA", hash: "SHA-256" }, privateKey, data)得到签名结果(ArrayBuffer) - 将签名转为 base64 字符串(
btoa(String.fromCharCode(...new Uint8Array(signature))))便于展示或嵌入 PDF/表单 - 签名结果本身不含原始数据,需配套保存原文或其哈希值(如 SHA-256 摘要),否则无法验证
防篡改校验:公钥本地验签即可确认
验证方只需拿到原始数据、公钥和签名三者,就能在任意离线环境(如打印后的扫码页面、离线文档查看器)完成校验:
- 先用
subtle.importKey("spki", spkiBytes, { name: "ECDSA", namedCurve: "P-256", hash: "SHA-256" }, true, ["verify"])导入公钥 - 将 base64 签名还原为
Uint8Array,原文同样编码为字节数组 - 执行
subtle.verify({ name: "ECDSA", hash: "SHA-256" }, publicKey, signature, data) - 返回
true表示:数据未被修改 + 签名确实由对应私钥生成;任一改动(哪怕一个空格)都会返回false
关键注意事项与避坑点
ECDSA 在 Web Crypto 中已稳定支持(Node.js v19+ 和所有现代浏览器),但实际落地需注意:
- P-256 是兼容性最好、性能最优的曲线,避免使用 P-521(部分旧浏览器不支持)
- 签名输出是 DER 编码格式,长度不固定(约 70–72 字节),不要假设为固定长度 hex 字符串
- 不能跳过哈希步骤:Web Crypto 的 ECDSA 签名接口内部自动执行 SHA-256 哈希,不可传入已哈希的数据(否则会二次哈希导致失败)
- 跨平台验证时,确保其他系统(如 Java、Python)使用相同参数:curve=P-256、hash=SHA-256、signature format=DER
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!











