做了一些更新,现在把 private 单独放到一个路径下面,同时把私人也从 post 列表移除,从另一个地址进去。如此页面的观感就好多了。同时也对整个处理的过程进行了大幅修改,重写了原来的 script 脚本,并用 Deno 实现了主要逻辑。Shell 脚本主要是用来协调 Deno 脚本的运行的。

因为 AES 生成的结果不固定,导致 git 固定上传上去时,总会对这些文件进行修改,非常麻烦,于是我决定做了一个分离。将加密后的 md 文件上传,同时 ignore 未加密的文件。每次会生成一个 hash 值用来校验变动,如果变动,则进行文件同步。至于生成后的页面,简单加密一下就不管了,因为这里的变动本来就很杂。

这里就是一个缓存的思路,如果不做缓存的话,逻辑是根本做不出来的。同时,用 Shell 脚本写主逻辑实在是太累人了,用 Python ,用 Deno ,哪个都好,就是不要用 Shell 写。


之前我看过某位的博客,发现他的有些博文是前端加密处理的。简单来说,就是后端提前将页面加密好,由前端输入密码来进行解密,如果密码解开失败就会报错。缺点是显而易见的,加密算法基本是公开的,而且也不限制用户的解密次数,解开只是时间问题。但这个方法没有想象的那么糟,因为只要你对加密算法和密钥用点心,其实这个密文也不好破解。而且,对于静态博客页来说,成本低廉,便宜划算,这些密文也并非机密。

我垂涎这个功能挺久了。我的博客是采用 Hugo 生成的,但 Hugo 的源码并不支持这种操作。事实上,我也考虑过改 Hugo 源码,但这样需要改动 Hugo 的架构,最后还是放弃了。于是我尝试修改我原先的部署策略,并借助一套自动化的脚本来完成。

首先要制定整体流程

实际开发中其实还考虑到几个问题:

  1. 反复加密保证只加密一次。
  2. 反复解密保证只解密一次。
  3. 开发过程中保证博文处于解密状态。
  4. 最终上线状态需要能在本地查看。

因此最终流程与图中展示稍有不同。

最后实现其实不是尽善的,由于加密方法的问题,每次部署都会引起密文变动。对我而言,不好不坏吧,可以的话,还是希望能够固定密文。

对 Markdown 和主题的处理

首先,要将需要加密的 Markdown 头部设置 private: true ,同时放到 private 文件夹下。

接下来我们需要修改模板主题。主题需要考虑三点,第一是 summary ,内容不能外泄,第二是 rss ,第三是头部 meta 信息。设置 private: true 可以让我们直接用 .Params.private 来判断是否需要展示博文信息。我没有对字数、categories 和 tags 动手,主要是因为没有必要。

加密脚本

编写加密是整个工作的核心。一般你只要选个合适的算法,确保加密解密的正确性,其实也就到头了。

前端加密我使用 crypto-js ,但后端用什么呢?我尝试了一下 Python ,很难等效,但又不想用 Node ,于是用了 Deno 。现在新版的 Deno 可以使用 npm 的包了,我引用了 crypto-js 。为什么不用 Deno 自己的加密呢? Deno 自己实现的加密是 Web Crypto ,属于 low level 的加密原语,用起来十分难受。况且加密解密都用 crypto-js 主要是为了避坑。

Deno 还提供专门的 DOM 解析器,用来保持和浏览器行为一致,不过需要额外引用。操作起来还行。

加密 Markdown

加密 Markdown 需要通过头部的 private 判断该文件是否值得加密,这是其一。判断密文是否已经被加密过了,这是其二。

但我目前处理了第一点,第二点我是在流程上解决的。

加密 HTML

加密 HTML 与加密 Markdown 面临同样的问题,但 HTML 还算简单。

我们加密 HTML 的过程是这样的,首先提取中间的 body 部分,然后加密整个 body 的 HTML ,最后将密文作为注入的值传入到新的模板上。借助 DOMParser ,我们可以像在浏览器上一样操作 HTML 的 DOM 节点。同时,生成的新模板,我们可以向其中放置 Detect DOM ,只要探测到这个 DOM ,我们就跳过加密。实现上是容易的。

部署

部署分为预部署和正式部署。两者主要的加密解密流程是基本一致的,且与前面的流程图相差不多。

预部署需要在我本地运行,我个人选择了 php -S 来查看效果。而正式部署一直是用的 Web hooks ,这部分没有变,只不过我本地写在 hooks 里的脚本不能用了,全部使用我自己写的 blog 脚本函数处理。

结语

目前,这一顿操作下来,最大的快乐是顺带学习了一些加密算法。我昨天试了很久,由于 Python 和 crypto-js 在对字节的认识上不同,导致我踩了很多坑。同时我也试过了 Web Crypto ,这玩意儿还是有待成熟。不过,我最大的惊喜是 Deno ,它比以前成熟许多了,个人感觉 Deno 比 Node 适合 SSR 。 Node 现在也在逐渐与浏览器兼容,大前端是 Node 未来的方向。 winter 协议还在孵化,但我估计是未来的趋势了。