Tip
通过本文,你将了解:
- 如何更方便的使用Li4n0/hugo_encryptor
- “PY_SSIZE_T_CLEAN macro must be defined for ’#’ formats” 报错的解决方法
- 简易修改
Note
建议先参考本文利用Github Action
将博客部署到Github Page
上获得最佳体验。
前言
博客偶尔想放些涉及个人生活比较深入的东西,但又只希望与接触比较深的人或者部分相关人士查看。这种情况下设置个大家心知肚明的密码最好。
原理
简单来说,hugo-encryptor
加密流程如下:
- 利用
shortcode
渲染待加密内容 - 用一段python程序对渲染结果(
/public
文件夹下所有文件)进行匹配,加密待加密内容 - 部署
因此,如果只是配置了shortcode而没有运行加密程序的话,文章内容不会被加密。而具体配置过程也因此分成了
配置主题
、配置部署
两部分。
为主题引入hugo_encryptor
原作者给出的办法个人感觉不是很好看:
### Step 1: Install all the requirements of Hugo-Encryptor
$ git clone https://github.com/Li4n0/hugo_encryptor.git $ cd hugo_encryptor $ chmod +x hugo-encryptor.py $ pip install -r requirements.txt
### Step 2: Create a symlink (Optional)
$ ln -s /absolute/path/to/hugo_encryptor/hugo-encryptor.py hugo-encryptor.py
### Step 3: Symlink `shortcodes/hugo-encryptor.html` into the shortcode directory of your blog:
$ mkdir -p /path/to/your/blog/layouts/shortcodes $ ln -s /absolute/path/to/hugo_encryptor/shortcodes/hugo-encryptor.html /path/to/your/blog/layouts/shortcodes/hugo-encryptor.html
我更倾向于将其直接放入主题中去,我的方法如下:
- 找到主题对应的
layouts/partials/shortcodes
文件夹,在里面新建一个文件夹hugo-encryptor.html
。 - 将以下代码复制粘贴入其中:{{< accordion “点击查看代码” >}}
{{ $_hugo_config := `{ "version": 1 }` }} {{/* ## Hugo Encrypt ### Params: -`password`: require param - Simple {{% hugo-encryptor "your password" %}} yourcontent {{% /hugo-encryptor %}} */}} {{/* DEFAULTS */}}
<div class="hugo-encryptor-container"> <div class="hugo-encryptor-prompt"> {{ if eq .Site.Params.hugoEncryptorLanguage "en-us" }} <p>Part of this article is encrypted with password:</p> {{ else }} <p>文章的部分内容被密码保护:</p> {{ end }} </div> <div class="hugo-encryptor-form"> <input class="hugo-encryptor-input" placeholder='{{ if eq .Site.Params.hugoEncryptorLanguage "en-us" }}Please input the password{{ else }}请输入密码{{ end }}' /> <input class="hugo-encryptor-button" type="button" value='{{ if eq .Site.Params.hugoEncryptorLanguage "en-us" }}Click to verify{{ else }}点击验证{{ end }}' onclick="_click_handler(this)" /> </div> <div class="hugo-encryptor-cipher-text" data-password="{{ .Get 0 }}" style="display: none;" > <span style="display: none;">--- DON'T MODIFY THIS LINE ---</span> {{ .Inner }} </div></div>
{{}}
- 找到主题对应header部分的模板,在其末尾添加:{{< accordion “点击查看代码” >}}
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/crypto-js.min.js"></script><script> const _do_decrypt = function (encrypted, password) { let key = CryptoJS.enc.Utf8.parse(password); let iv = CryptoJS.enc.Utf8.parse(password.substr(16));
let decrypted_data = CryptoJS.AES.decrypt(encrypted, key, { iv: iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7, }); return decrypted_data.toString(CryptoJS.enc.Utf8); };
const _click_handler = function (element) { let parent = element.parentNode.parentNode; let encrypted = parent.querySelector( ".hugo-encryptor-cipher-text", ).innerText; let password = parent.querySelector(".hugo-encryptor-input").value; password = CryptoJS.MD5(password).toString();
let index = -1; let elements = document.querySelectorAll(".hugo-encryptor-container"); for (index = 0; index < elements.length; ++index) { if (elements[index].isSameNode(parent)) { break; } }
let decrypted = ""; try { decrypted = _do_decrypt(encrypted, password); } catch (err) { console.error(err); alert("Failed to decrypt."); return; }
if (!decrypted.includes("--- DON'T MODIFY THIS LINE ---")) { alert("Incorrect password."); return; }
let storage = localStorage;
let key = location.pathname + ".password." + index; storage.setItem(key, password); parent.innerHTML = decrypted; };
window.onload = () => { let index = -1; let elements = document.querySelectorAll(".hugo-encryptor-container");
while (1) { ++index;
let key = location.pathname + ".password." + index; let password = localStorage.getItem(key);
if (!password) { break; } else { console.log("Found password for part " + index);
let parent = elements[index]; let encrypted = parent.querySelector( ".hugo-encryptor-cipher-text", ).innerText; let decrypted = _do_decrypt(encrypted, password); elements[index].innerHTML = decrypted; } } };</script>
{{}}
Warning
请注意,此时文章还未被加密,需完成python的配置才行。
即可完成主题部分的配置。
配置部署
Note
建议先参考本文利用Github Action
将博客部署到Github Page
上获得最佳体验。本地运行属实麻烦,下文假设你使用Github Action
将博客部署到Github Page
上。
我们再回顾一下hugo-encryptor
的工作原理:
- 利用
shortcode
渲染待加密内容 - 用一段python程序对渲染结果(
/public
文件夹下所有文件)进行匹配,加密待加密内容 - 部署
在上一小节中,我们已经实现了1. 利用
shortcode渲染待加密内容
,而由于我们使用Github Action
,我们可以将23两步结合起来,实现全自动加密,避免忘记运行加密程序导致隐私泄漏。
步骤如下:
- 在博客仓库创建一个文件夹
hugo_encryptor
,将Li4n0/hugo_encryptor中的hugo-encryptor.py
与requirements.txt
放入其中。 - 对原有的部署工作流如此修改:
...env: ... HUGO_ENCRYPTOR_PATH: ./hugo_encryptor ...jobs: build: steps: ... - uses: actions/setup-python@v4 with: python-version: '3.9'
- name: Install Python and Dependencies run: | sudo apt-get update sudo apt-get install -y python3 python3-pip pip3 install -r ${{ env.HUGO_ENCRYPTOR_PATH }}/requirement.txt
- name: Build Hugo site run: hugo --minify --gc
- name: Encrypt private posts run: | python3 ${{ env.HUGO_ENCRYPTOR_PATH }}/hugo-encryptor.py env: HUGO_ENCRYPTOR_PATH: ./hugo_encryptor # Adjust this path based on where your `hugo_encryptor.py` script is located ...
其中,python版本选择3.9
最佳,3.10
及以上会报错:“PY_SSIZE_T_CLEAN macro must be defined for ’#’ formats”。此时可以选择以下两种做法:
- 回退
3.9
版本python(推荐) - 重新用pip卸载再安装
pycryptodome
库
至此,基本配置结束。 {{< accordion “参考workflow” >}}
name: Deploy Hugo site to Pages
on: # Runs on pushes targeting the default branch workflow_dispatch: push: branches: ["master"]
# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pagespermissions: contents: read pages: write id-token: write
# Environment variables available to all jobs and steps in this workflowenv: HUGO_ENV: production HUGO_VERSION: "0.115.4" GO_VERSION: "1.20.5" NODE_VERSION: "18.15.0" TINA_CLIENT_ID: ${{ vars.TINA_CLIENT_ID }} TINA_TOKEN: ${{ vars.TINA_TOKEN }} HUGO_ENCRYPTOR_PATH: ./hugo_encryptor
jobs: build: runs-on: ubuntu-latest
permissions: contents: write # Allow write access to commit changes to the repository
steps: - uses: actions/checkout@v4 with: submodules: "recursive"
- name: Cache Hugo resources uses: actions/cache@v4 env: cache-name: cache-hugo-resources with: path: resources key: ${{ env.cache-name }}
- uses: actions/setup-go@v5 with: go-version: "^1.17.0" - run: go version
- name: Setup Hugo uses: peaceiris/actions-hugo@v2 with: hugo-version: "latest" extended: true
- uses: actions/setup-python@v4 with: python-version: "3.9"
- name: Install Python and Dependencies run: | sudo apt-get update sudo apt-get install -y python3 python3-pip pip3 install -r ${{ env.HUGO_ENCRYPTOR_PATH }}/requirement.txt
- name: Build Hugo site run: hugo --minify --gc
- name: Encrypt private posts run: | python3 ${{ env.HUGO_ENCRYPTOR_PATH }}/hugo-encryptor.py env: HUGO_ENCRYPTOR_PATH: ./hugo_encryptor # Adjust this path based on where your `hugo_encryptor.py` script is located
- name: Upload artifact uses: actions/upload-pages-artifact@v1 with: path: ./public
- name: Echo CNAME run: echo ${{ secrets.CNAME }} > ./public/CNAME
- name: Deploy Web uses: peaceiris/actions-gh-pages@v3 with: PERSONAL_TOKEN: ${{ secrets.PERSONAL_TOKEN }} EXTERNAL_REPOSITORY: HaleyCH/HaleyCH.github.io PUBLISH_BRANCH: master PUBLISH_DIR: ./public commit_message: ${{ github.event.head_commit.message }}
{{}}
为encryptor添加密码提示
为了让目标受众知道我设置的密码是什么,有必要增加密码提示功能,这比较简单,只需将
{{ else }} <p>文章的部分内容被密码保护:</p>{{ end }}
改为
{{ else }} <p>文章的部分内容被密码保护{{ if .Get 1 }},提示 “{{ .Get 1 }}”{{ end }}:</p>{{ end }}
即可。最终成果如下所示(密码hugo)。
{{% hugo-encryptor “hugo” “此博客用的框架” %}}
对,就是hugo。 {{% /hugo-encryptor %}}