Skip to content

wangshengithub/staticshield

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

StaticShield

零后端的静态网页加密保护工具——用密码把 HTML 变成「自解密页面」,部署到任何静态托管后,访客输入正确密码即在浏览器端实时解密,全程无需服务器。

StaticShield 把单个 HTML(或整站打包后)用 AES-256 加密成一份自包含的 .html:没有密码时只显示加密保护页,输入正确密码才在浏览器端还原原始内容。适合内部文档、付费内容预览、临时私密页面等「门禁式」访问控制。

功能特性

  • 单文件 / 多文件网页加密:单个 HTML 直接加密;--bundle 可把整站(HTML + css/js/图片)内联打包后加密
  • 本地 CLI + Web GUI:命令行批量处理,或浏览器图形界面(本地后端,支持多客户端并行)
  • 浏览器端实时解密,零后端:产物是自包含 HTML,部署到 GitHub Pages / 对象存储 / Nginx 等任意静态托管即可
  • 随机密码生成:CSPRNG 生成强密码(默认 8 位,含数字 + 大小写字母),告别弱密码
  • 记住我 / 分享链接 / 密码提示:本机免重复输入;URL Hash 自动解密链接;可选提示文案
  • 重叠加密:对已加密产物再次加密,多层独立密码逐层剥解
  • 卡片风解密页:默认沿用原网页 favicon 作 Logo,自定义错误提示(非原生 alert),配色统一

技术规格

对称加密 AES-256-CBC(PKCS#7 填充)
密钥派生 PBKDF2-SHA256(默认)/ SHA-512,迭代 1,000,000
完整性 HMAC-SHA256(Encrypt-then-MAC,先验签后解密,防篡改)
解密端 浏览器 WebCrypto,零依赖
加密端 本地 Node.js 脚本(CLI)+ 本地 Web GUI(浏览器图形界面)
运行环境 Node.js ≥ 18(CLI / GUI 后端),现代浏览器(解密)

快速开始

获取工具(零运行时依赖,无需 npm install):

git clone <仓库地址> staticshield && cd staticshield   # 或直接下载源码

环境要求:Node.js ≥ 18(内置 WebCrypto)。

# 加密单个文件(交互输入密码,不回显)
node encrypt.js page.html

# 多文件 + 指定密码 + SHA-512 + 输出目录
node encrypt.js a.html b.html -p MyPwd123 --sha512 -d ./dist

# 记住我 7 天 + 生成分享链接 + 提示文案
node encrypt.js secret.html --remember 7 --share --hint "我的生日"

# 多文件网页打包加密(HTML + 独立 css/js/图片)
node encrypt.js index.html --bundle -p MyPwd123

# 生成随机密码并用于加密(12 位,自动打印密码)
node encrypt.js page.html --gen-pwd 12

# 仅生成一个随机密码(默认 8 位)
node encrypt.js --gen-pwd

# 打开图形界面(Web GUI)
node encrypt.js --gui

加密后生成同名 .html(自解密页面)。直接部署或双击打开,输入密码即可查看。若输出与源文件同路径,会自动改名为 xxx.encrypted.html 以免覆盖源文件。

工作原理

[加密]  原始 HTML ──(密码 + AES-256 + PBKDF2 + HMAC)──▶ 自解密 .html
[部署]  上传到任意静态托管(GitHub Pages / 对象存储 / CDN / Nginx …)
[解密]  访客打开页面 ──▶ 输入密码 ──▶ 浏览器 WebCrypto 还原原始 HTML

加密端(CLI / GUI 后端)与解密端共用同一份 WebCrypto 加密核心(src/crypto-core.js),产物格式一致、单点维护。

CLI 参数

参数 说明 默认
<filename> 待加密 HTML 文件,支持多个
-p, --password <pwd> 加密密码;未提供则交互式提示输入(不回显) 交互输入
--sha512 使用 PBKDF2-SHA512 PBKDF2-SHA256
-d, --directory <dir> 输出目录 当前目录
--remember <days> 记住我过期天数,0 = 永不过期 不启用
--share 额外生成可自动解密的分享链接(密码置于 URL hash) 关闭
--hint <text> 密码提示文案
--logo <path> 自定义解密页 Logo(默认取原网页 favicon) 原网页 favicon
--bundle 先把 HTML 引用的本地 css/js/图片内联成单文件再加密(多文件网页) 关闭
--gen-pwd [n] 生成 n 位随机密码(默认 8,含数字 + 大小写字母)用于加密;不带文件时仅生成 关闭
--gui 启动本地 GUI 后端(127.0.0.1)并打开浏览器 关闭
-h, --help 显示帮助

多文件网页(--bundle

当网页是「index.html + 独立 css/ + js/ + 图片」的多文件结构时,直接加密 index.html 会丢失或暴露这些资源。加 --bundle,工具会先把 HTML 引用的本地相对路径资源全部内联成单个自包含 HTML,再走加密:

  • <link rel=stylesheet><style>(递归内联 css 内 @importurl()
  • <script src> → 内联 <script>严格保持原加载顺序与其他属性
  • <img/source/audio/video/track>.src<video poster>srcset、favicon → data: URI
  • http(s)、CDN 等绝对 URL 原样保留;相对路径沙箱约束在源网页目录内,防路径遍历

解密端无需任何改动(打包后仍是单 HTML)。代价是产物体积增大(图片 base64 膨胀约 33%)。

Web GUI(本地后端)

node src/build-gui.js     # 由源码生成 gui/index.html(改前端源码后需重新生成)
node encrypt.js --gui     # 启动本地后端(127.0.0.1)并打开浏览器

--gui 启动一个仅绑定 127.0.0.1 的本地服务,浏览器访问后:

  • 单文件:选一个 HTML → 设密码 → 加密下载
  • 整个文件夹:选网页所在文件夹(含 index.html + css/js/图片)→ 后端打包内联(同 --bundle)→ 加密下载
  • 密码框旁「🎲 生成」按钮可即时生成随机密码(可改位数)

多个客户端(标签/设备)可同时访问并行加密,文件不离开本机,终端 Ctrl+C 停止服务。

Web GUI 必须通过本地服务访问;直接双击 gui/index.html 无法工作(前端需调用后端 API)。

解密页行为

  • 卡片风格输入框(主背景 #ddcdef、按钮 #9932cc、错误 #8b0000),默认显示原网页 favicon 作为 Logo
  • 密码显示/隐藏切换(眼睛图标);错误时卡片内自定义提示 + 抖动反馈(不使用原生 alert
  • 自动解密优先级:URL Hash 密码 → 本机「记住我」→ 手动输入
  • 解密成功:清除 URL hash → 用原 HTML 替换当前文档 → 恢复原始 <title>

安全说明

  1. PBKDF2 百万次迭代 + 随机 salt,显著抬高暴力破解成本
  2. HMAC 先验后解:密文被篡改则验签失败,避免 padding oracle 类风险
  3. 加密/签名密钥隔离:PBKDF2 派生 64 字节,前 32 为 encKey、后 32 为 macKey
  4. 随机 IV/salt:相同文件 + 密码每次产出不同密文
  5. 分享链接走 URL Hash:密码不随 HTTP 请求发送到服务器;解密成功后清除 hash。但链接本身即含密码,请按需分享
  6. 记住我不存原始密码:仅存 PBKDF2 派生密钥材料 + 过期时间于本机 localStorage,过期自动清除;公共设备请勿勾选
  7. 同源注意:记住我的派生密钥存于 localStorage,可被同源脚本读取。同一托管域下若托管多个加密页或存在 XSS,存在被跨页读取的可能;高敏感场景请勿勾选记住我

⚠️ 浏览器端解密意味着密文会下发到客户端,StaticShield 适用于「门禁式」访问控制(防直接查看/抓取),不构成对资深逆向者的绝对防护。

常见问题

忘记密码能找回吗? 不能。工具本身无后端,密码不存储于任何服务器,PBKDF2 为单向派生——丢失密码即内容无法恢复。建议用 --gen-pwd 生成后妥善保存。

安全性如何? 采用 AES-256 + PBKDF2 百万次迭代 + HMAC 验签,对标业界标准。但密文会下发到客户端浏览器,属「门禁式」访问控制(防直接查看/抓取),无法阻止资深逆向者;绝密内容请使用更强的访问控制方案。

支持哪些部署平台? 任何能托管静态文件的位置:GitHub Pages、GitLab Pages、Vercel/Netlify 静态、对象存储(S3/OSS/COS)、Nginx/Apache,甚至直接双击本地打开(file://)。

多文件网页(带 css/js/图片)怎么办?--bundle(CLI)或 Web GUI「整个文件夹」模式,工具先内联打包成单 HTML 再加密。

能加密多大的文件? 理论上无硬性限制,但产物是单 HTML(图片经 base64 膨胀约 33%),超大站点体积会明显增大,更适合单页或中小型站点。

产物能在纯 HTTP 下解密吗? 不能。浏览器 WebCrypto 仅在安全上下文(https://localhostfile://)下可用;纯 HTTP 部署会提示需 HTTPS。请通过 HTTPS 访问。

项目结构

staticshield/
├── encrypt.js              # CLI 入口
├── src/
│   ├── crypto-core.js      # 同构加密核心(Node + 浏览器共用,单点维护)
│   ├── render.js           # 产物 HTML 渲染(同构,CLI 与 GUI 共用)
│   ├── decrypt-ui.js       # 浏览器解密运行时(内嵌进每个产物)
│   ├── template.js         # 组装产物(Node,调 render)
│   ├── bundle.js           # 多文件网页打包内联(Node)
│   ├── password.js         # 随机密码生成(同构 CSPRNG)
│   ├── favicon.js          # 提取原网页 title/favicon(Node)
│   ├── cli-args.js         # CLI 参数解析
│   ├── gui-logic.js        # Web GUI 前端逻辑
│   ├── server.js           # Web GUI 本地后端(HTTP,127.0.0.1)
│   └── build-gui.js        # 由源码生成 gui/index.html
├── gui/
│   └── index.html          # 生成的 Web GUI(由 build-gui.js 产出)
└── package.json

单点维护crypto-core.js(算法)、render.js(产物结构)、bundle.js(打包)、password.js(密码生成)各一份,CLI 与 Web GUI 后端都复用它们,避免两套实现不一致。改 src/ 下源码后,CLI 产物自动用最新核心/UI;改 GUI 前端源码需重跑 node src/build-gui.js

开发

node src/build-gui.js   # 重建 Web GUI(修改前端源码后执行)

浏览器手动验证清单

以下浏览器交互行为建议人工抽测验证:

  1. 基础解锁:打开加密产物 → 输入正确密码 → 原页面还原、title 恢复
  2. 错误反馈:输错密码 → 卡片内红色提示 + 抖动(非 alert)
  3. 密码显隐:点击眼睛图标 → 明文/密文切换
  4. 分享链接:打开 xxx.html#pwd=<密码> → 自动解密并清除地址栏 hash
  5. 记住我:勾选解锁 → 关闭再打开 → 免密自动解密;--remember 0 为永久
  6. 重叠加密:对产物再次加密 → 逐层输入密码还原
  7. Web GUI--gui 启动 → 单文件模式加密下载 → 切换「整个文件夹」选多文件网页 → 产物可被正常解密

许可证

MIT


项目地址:github.com/wangshengithub/staticshield · MIT License

About

一款安全又便捷的网页加密工具。采用 AES-256 + PBKDF2 百万次迭代 + HMAC 验签,密码与解密全程留在浏览器本地;一条命令或图形界面即可把 HTML(乃至整站 css/js/图片)加密成自解密页面,部署到任意静态托管。Secure, effortless HTML encryption: AES-256, PBKDF2 (1M iterations), HMAC, with fully client-side decryption. Encrypt an entire site (CSS/JS/images) into a self-decrypting file via one command or GUI—deploy anywhere static.

Topics

Resources

Stars

2 stars

Watchers

0 watching

Forks

Contributors