news 2026/11/3 11:47:02

零依赖Excel加密:hucre如何用WebCrypto实现Agile密码保护

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
零依赖Excel加密:hucre如何用WebCrypto实现Agile密码保护

零依赖Excel加密:hucre如何用WebCrypto实现Agile密码保护

【免费下载链接】hucreZero-dependency spreadsheet engine. Read & write XLSX, CSV, ODS. Pure TypeScript, works everywhere.项目地址: https://gitcode.com/gh_mirrors/hu/hucre

hucre 是一个零依赖的电子表格引擎,能读取和写入 XLSX、CSV、ODS 等格式,全部用纯 TypeScript 编写。除了基础的读写能力,它还有一个常被忽视的硬核功能——Excel 文件加密:通过平台原生的 WebCrypto API 实现 ECMA-376Agile 密码保护(Excel 2010+ 采用的加密方案),在 Node、Deno、Bun、Cloudflare Workers 乃至浏览器里都能直接运行,不需要引入任何密码学第三方库。

什么是 Agile 加密?

当你用 Excel 给文件"设置密码"时,从 2010 版本起,Excel 默认使用的就是Agile 加密(定义于 ECMA-376 标准,细节由 [MS-OFFCRYPTO] 规范描述)。它的核心配方是:

  • AES-256-CBC加密文件内容
  • SHA-512哈希派生密钥,默认迭代100,000 次(称为 spin count)
  • HMAC-SHA512校验数据完整性,防止密文被篡改
  • 整体打包进OLE2/CFB 复合二进制容器(而不是普通的 ZIP)

hucre 对这一整套流程做了完整的加密与解密实现,源码集中在 src/xlsx/crypto/ 目录下的两个文件:

文件职责
src/xlsx/crypto/agile.tsAgile 密码学的全部逻辑:密钥派生、AES-CBC 分段加解密、HMAC 校验
src/xlsx/crypto/cfb.ts最小化的 OLE2/CFB 容器读写器

加密与解密:各一行 API

对使用者来说,Agile 加密被封装得非常轻——写文件时多传一个encryption选项,读文件时多传一个password选项,就完事了:

import { writeXlsx, readXlsx } from "hucre" // 写一个带密码保护的 XLSX const encrypted = await writeXlsx({ sheets: [{ name: "Secret", rows: [["pin", 1234]] }], encryption: { password: "hunter2" }, }) // 带上密码读回来 const wb = await readXlsx(encrypted, { password: "hunter2" })

这套选项在所有读取入口都生效:read()会自动探测容器类型并透明解密,readObjects()和streamXlsxRows()同样支持传password;往返编辑路径saveXlsx(wb, { encryption: { password } })也走同一个加密器(见 src/xlsx/roundtrip.ts)。

密钥是如何从密码中"变"出来的?

密码本身不能直接当密钥用。hucre 按 MS-OFFCRYPTO 规范实现了完整的派生链,核心在 passwordChain:

  1. 加盐:随机生成 16 字节的盐值,与 UTF-16LE 编码的密码拼接后做首次 SHA-512;
  2. 迭代拉伸:用 4 字节计数器反复哈希,默认循环 100,000 次(spinCount),让暴力破解的成本线性放大——这就是为什么加密一个文件会有可感知的耗时;
  3. 派生多组块密钥:从哈希链上再派生出 verifier 密钥、密钥加密密钥、数据密钥等,各司其职;
  4. 随机密钥包裹:真正的包密钥secretKey是随机生成的 32 字节,用上面的派生密钥 AES-CBC 加密后存进EncryptionInfo元数据中。

解密时则反过来:用你输入的密码重走一遍派生链,解出随机验证输入和它的哈希值,两者对上才认为密码正确(见 deriveSecretKey),否则抛出DecryptionError。

密文怎么存?——分段 AES-CBC + 完整性校验

Excel 的文件体按4096 字节分段,每段用独立的 IV 做 AES-CBC 加密(IV 由盐值加段索引哈希而来,见 encryptPackage)。这里有个精巧的工程细节:WebCrypto 的 AES-CBC总是强制 PKCS#7 填充,而 OOXML 的分段是"裸"的块对齐数据。hucre 用两个经典技巧绕过它——解密时追加一个精心构造的密文块诱使 WebCrypto 把填充块剥掉,加密时则丢弃尾部填充块(代码开头的注释 agile.ts 解释得很清楚)。

此外,hucre 还会验证<dataIntegrity>元素里的 HMAC:解出 HMAC 密钥后对整条EncryptedPackage流计算 HMAC-SHA512,不匹配就拒绝输出(见 verifyDataIntegrity)。这意味着密文哪怕被篡改一个字节,也不会静默地给你一份损坏的数据。

安全细节:不只是"能加解密"

几个容易被忽略的防线,hucre 都做了:

  • DoS 防护:spinCount来自不受信任的文件。恶意文件可以谎报一个天文数字的迭代次数,把 CPU 钉死几分钟。hucre 设了上限 MAX_SPIN_COUNT = 10,000,000(Office 自己只用 10 万),超上限直接拒绝解密;
  • 零依赖:所有密码原语直接调用crypto.subtle.digest、crypto.subtle.encrypt和crypto.getRandomValues(见 WebCrypto 原语层),没有任何 WASM 或纯 JS 的 AES 实现——这也是它能在 Cloudflare Workers 和浏览器里跑的原因;
  • 清晰的错误分层:忘了传密码抛 EncryptedFileError,密码错误或数据损坏抛 DecryptionError,两者语义分明,方便你在 UI 里分别提示"需要密码"和"密码不对";
  • 兼容 Excel 默认参数:加密默认使用 Excel 原生的 100,000 次迭代,产出的文件可被 Excel 直接打开;测试里也有专门的用例验证这个默认值下的端到端互通(encryption.test.ts)。

验证:加密文件到底"长"什么样?

从 test/encryption.test.ts 可以看到完整的行为契约:

  • 加密输出是 OLE2 容器而非 ZIP(isOle2Container(enc)断言为 true);
  • 无密码读取 →EncryptedFileError,错误密码 →DecryptionError;
  • openXlsx+saveXlsx可以"换密码":用第一个密码打开、用第二个密码重新保存,旧密码随即失效;
  • CFB 容器读写器对小型流(mini-stream)和大型流都做了往返验证。

小结

hucre 把一套工业级的 Office 文件加密——OLE2 容器、AES-256-CBC 分段、SHA-512 密钥拉伸、HMAC 完整性校验——完整地装进了零依赖的 TypeScript 里,全部密码运算借力平台自带的 WebCrypto。对使用者的最终体现却极简:写时传一个password,读时传一个password。如果你的项目需要给电子表格加上真正的密码保护,又不想为此引入一堆二进制依赖,src/xlsx/crypto/ 值得仔细读一读。

【免费下载链接】hucreZero-dependency spreadsheet engine. Read & write XLSX, CSV, ODS. Pure TypeScript, works everywhere.项目地址: https://gitcode.com/gh_mirrors/hu/hucre

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/11/2 15:51:02

USB2.0设备改造Type-C:5.1k电阻与CC引脚识别机制详解

说实话&#xff0c;我也干过这种“手痒”的事儿。手里一个老掉牙的USB2.0设备&#xff0c;接口要么是Micro-B要么干脆就是个大头USB-A&#xff0c;线材难找不说&#xff0c;插拔方向还得确认半天。换成Type-C之后&#xff0c;正反随便插&#xff0c;一条C口线通吃手机、电脑、充…

作者头像 李华
网站建设 2026/10/24 16:33:46

FCN全卷积网络入门:从分类网络到像素级语义分割的完整实践

简介&#xff1a;面向深度学习图像分割方向的学习者&#xff0c;这份FCN实战资源提供了从任意尺寸图像输入、特征图反卷积上采样到逐像素分类预测的完整流程&#xff0c;可帮助快速理解全卷积网络相对经典CNN的核心设计&#xff0c;并直接用于课程设计、算法对比或工程实践。压…

作者头像 李华
网站建设 2026/10/24 8:14:35

起重机检测YOLO数据集:从标注格式校验到训练避坑指南

简介&#xff1a;面向起重机crane目标检测任务&#xff0c;提供约2900张已标注图像数据及配套YOLO格式标签&#xff0c;类别为单一类别crane&#xff0c;适合作为计算机视觉初学者或进阶者的训练数据集。数据已完成训练集、验证集划分&#xff0c;可直接用于YOLOv5等主流检测框…

作者头像 李华
网站建设 2026/10/24 10:16:30

superpowers:AI编程代理的agentic skills框架与实操指南

1. 从“superpowers”说起&#xff1a;这套 agentic skills framework 到底在解决什么问题第一次看到 “superpowers” 这个词&#xff0c;很多人会以为是某个游戏模组或者某个超级英雄主题的插件。但如果你最近在折腾 Claude Code、Codex CLI 这类终端里的 AI 编程代理&#x…

作者头像 李华
网站建设 2026/10/24 18:40:22

Claude Code营销技能库marketingskills实战:SEO审计与CRO自动化

1. 从“marketingskills”说起&#xff1a;一个被低估的营销自动化切口第一次看到marketingskills这个词&#xff0c;是在翻 Claude Code 相关生态的时候。当时我的第一反应是&#xff1a;这不就是把营销方法论塞进 AI Agent 里吗&#xff1f;但仔细琢磨之后发现&#xff0c;它…

作者头像 李华