加密博客内容,使用密码访问

今天突然想用hexo博客来记录一些不想公开的内容,仅登录用户可见。显然,由于hexo生成的是静态文件,
所以这个需求不大现实,不过如果能通过输入密码访,解密之后,访问博客内容那也是极好的

方案设想

简单点,打开某一篇博客,先不能看到博客内容或者只能看到加密内容,弹出输入框,输入密码之后,解密,
密码正确则解密结果正确,否则解密结果错误,将解密结果替换原加密内容即可

加密解密

加解密使用crypto-js.js的AES算法,加解密算法显然不是很了解,直接使用该库中的接口

1
2
txt = CryptoJS.AES.encrypt(data.content, password).toString(); // 加密
CryptoJS.AES.decrypt(txt, pwd); // 解密

实现逻辑

其实逻辑很简单, 制作一个hexo插件,利用hexo filter, after_post_render, 在渲染完成之后,取到data.content 对其进行加密
并拼接解密js代码到content中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var password = getPassword();
var ciphertext = CryptoJS.AES.encrypt(data.content, password); // 加密
var txt = ciphertext.toString();

// 拼接加密后的内容及解密的js代码
data.content = '<div id="enc_content">' + txt + '</div>';
data.content = data.content + '<script src="/js/crypto-js.js"></script>';
data.content = data.content + '<script>'+
'var pwd = window.prompt("please input password","");' + // 弹出输入密码框
'var txt = document.getElementById("enc_content").innerHTML;' +
'var bytes = CryptoJS.AES.decrypt(txt, pwd);' +
'var plaintext = bytes.toString(CryptoJS.enc.Utf8);' +
'document.getElementById("enc_content").innerHTML = plaintext' +
'</script>';

源代码在这里, 里边也有具体使用的说明
测试页面在这里, 密码么,因为目前插件不能针对页面单独设置密码,所以就不说了(偷笑)

这只是个完成基本功能的插件,另外还可以做更多更强大的功能,当有需求的时候,再去完善

最后

需要注意的是,如果使用github来同步备份你的原始文件(md, hexo相关配置), 那么这个加密没什么卵用(因为github不付费的话只能创建public的仓库)
所以,要么github付费,设置repo为private, 要么就用其他方式(我选择使用了coding.net,可以免费创建私有仓库)


update: 2016/6/1

新需求:

  1. 前边提到的,不支持针对单个文章使用特殊密码的加密方式,那么现在支持了,上边的密码是 123456
  2. 既然是博客,肯定会用到图片,然而需要加密,所以图片不能随便放在一个通过直接的url就能访问的地方
  3. 都有图片了,那么针对自己图床的图片,提供一个base url那是极好的

1

这个实现很简单,在每一篇文章的header里边配置个属性,插件在获取密码的时候,再从文章里边看一下有没有就好了,当然文章里边配置的密码具有最高优先级

1
enc_pwd: 123456

有木有很简单?

2

这个有一个最重要的要求,图片不能像http://wwww.test.com/test.img 这样子可以直接就访问,否则如果加密的博客里边有图片,和没加密就没区别了。因为之前就听说过七牛,所以没什么犹豫,直接用它好了。私有存储空间,nodejs的sdk,有这两样,就可以开始动手了。
私有存储空间是免费的,怎么配置这里就不说了,很简单的东西。
重点说说nodejs的sdk的图片下载, 这里是官方给的例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var qiniu = require("qiniu");

qiniu.conf.ACCESS_KEY = 'Access_Key';
qiniu.conf.SECRET_KEY = 'Secret_Key';

//构建私有空间的链接
url = 'http://domain/key';
var policy = new qiniu.rs.GetPolicy();

//生成下载链接url
var downloadUrl = policy.makeRequest(url);

//打印下载的url
console.log(downloadUrl);

其中, access key, secret key在你自己的七牛账户中可以查看到
url 中, domain为域名,七牛会给一个默认的,不过有一些限制,但是测试时够用了
key为图片名,也就是你上传的图片的名字
这样子就可以生成一个带有token的url,从而获取到图片了

那么,在hexo中,怎么用呢?

1
2
3
4
data.content = data.content.replace(/<img [^>]*src=['"]([^'"]+)[^>]*>/gi,
function (match, url) {
return match.replace(url, genUrl(url));
});

取到文章内容,正则表达式替换所有img标签中的url就好了

_config.yml配置就是这样子了

1
2
3
4
encrypt:
replace_all_url: true # this will replace img url in all posts
qiniu_ak: you access key
qiniu_sk: you serect key

在每个post中可以做如下配置, 来确定在本篇文章中是否需要替换url

1
enc_replace_url: true

这里的配置具有最高优先级

3

url替换都有了,加个baseurl 也不是什么难事了。
在配置文件中配置一下,然后跟上边的url拼接一下就好了
配置:

1
2
encrypt:
base_url: your base url

TODO

如果图片在more之前,那么在主页就会出现图片资源找不到的情况,因为more之前的内容没有做替换
还不知道这个图片的url有效期是多久


update: 2016/06/03

图片url有效期

上面提到的图片url的有效期,理论上是3600秒,即1小时, 超过1小时就获取不到图片了,作为博客,可不想这么短,
太短了,所以呢,_config.yml中增加配置选项

1
img_url_ttl: 86400000 # 1000 days

所以,这个url在1000天内就有效了。

base64内嵌图片到html

why?

  • 我没有图床
  • 七牛太麻烦了,我不想去弄

好吧,其实没啥理由,就是突然发现可以base64图片之后内嵌到html中,所以,我就做了这么个支持

用法

1
2
encrypt:
type: base64 # 只需要配置这个就够了

然后使用图片

1
![](you img path) 		# 注意这里是路劲,绝对路径好说,直接写就是了,相对路径的话,是相对于文章对应的资源路径(就是hexo n 文章名  的时候,会在文章.md文件对应的目录下生成一个 文章名 的新目录, 相对路径的根目录就是这个目录)

需要注意的一点:
要确保不会有插件将上面提到的 文章名 目录下的资源在 hexo g 时拷贝到public目录
所以建议使用绝对路径,将其放在其他目录下

原理

以base64编码的方式读取图片文件,然后替换2016/06/02中提到的url就好了

more

具体用法见这里


update: 2017/02/13

早就该更新了的,但是因为懒,一直没写

在更新之前,一个最大的问题,解密弹出框太丑了,开始因为时自己用也就忍了,但是想了想,还是做各模板支持吧,所以就有了

新加配置支持 template

首先,如果你已经使用了此插件,并且不想在做任何修改,那么只需要升级插件即可

如果你觉得解密的输入框按钮等和你的主题不太搭调,你又会写html css, 那么自己动手,定义template吧

使用方式:

_config.yml中用法如下

1
2
encrypt:
template: '你的模板html和js,或许还有css'

单独的post中用法如下

1
enc_template: '你的模板html和js,或许还有css'

还有一点:
在你模板中,一定要有一行js代码,调用doDecrypt(password)函数完成解密

最后一点:
博主css和html都是一边搜索一边写出来的,所以默认的模板很丑,但是能用。如果你有更好的模板,欢迎提fork源码修改并添加pull request,或留言告诉我

TODO:

  • 模板文件支持,方便扩展不同模板
文章目录
  1. 1. 方案设想
  2. 2. 加密解密
  3. 3. 实现逻辑
  4. 4. 最后
  • update: 2016/6/1
    1. 1. 新需求:
    2. 2. 1
    3. 3. 2
    4. 4. 3
    5. 5. TODO
  • update: 2016/06/03
    1. 1. 图片url有效期
    2. 2. base64内嵌图片到html
    3. 3. 用法
    4. 4. 原理
    5. 5. more
  • update: 2017/02/13
    1. 1. 新加配置支持 template
    2. 2. TODO:
  • ,