(其实就是一个如何安全地留遗嘱之类的程序。
通过互联网的使用行为来在发生不测之后发出通知的服务已经有很多了,比如早年的 deathswitch ,现在还有 Google 的闲置账户管理。但是,( 1 )平时将敏感信息寄放在这些服务上,让任何可能看到的人一眼就能看到,我并不放心;( 2 )登录上去,挨个更新给多个人的留言也不方便,( 3 )有些服务也限制了能发送的邮件的最大数量……于是见到各种缺点之后,我想到了这个用密码来加密存放信息的程序。
先说用法:
演示: http://area51.neoatlantis.info/demo.manjusaka.html
进入之后输入解密密码,有 3 个分类可选,密码如下:
test -> test
parent -> a3ejtdxnl3tula2gcfqvfz45o4b2mt55
friend -> 55kzqzupo4fzdbtexmr32rms5fhns45k
问题的答案,生日是1970-01-01, ID 是0123456789ABCDEFG.
这个程序最后会输出一个单一的网页,自带用来解密和显示内容的 js ,所以十分适合将网页拷贝给别人,或者——最好是——放到个人网站>个人简介之类的地方预先公开(避免出事情之后找不到)。
程序的主页在 https://github.com/neoatlantis/manjusaka
用git clone之后,仿照sample-messages/下的格式建立自己的messages/目录,用 YAML 格式书写内容,之后用make即可。需要browserify和uglify。范例目录中的_acl.yaml有对参数的注释。
技术细节
访客来解密信息需要经过 3 个步骤:
- 首先需要输入用于解锁某个消息分类的密码。这个密码通过现有的邮件服务在不测之后发出。
- 程序验证存在(1)所提到的密码之后,将可能解密的消息找出来。这些消息还可能要求访客回答一系列问题。
- 访客在回答了所有的问题之后,问题答案将一并与(1)的密码合并生成对消息的解密密钥,解密消息。
为了保证兼容性,这个程序虽然只使用了对称加密,也用了openpgp.js这个库。程序生成页面时在本地用 gpg+对称口令加密各种数据,然后在网页里用 js 解密。
留言信息的解密密钥由 消息分类的密码 和 问答题的答案 组成:
- 前者的安全性不用多说,只要密码足够长就可以。用来判断消息分类的密码是否正确的方法是将一个截断的密码的 SHA256 放置在结果网页中。由于消息分类密码本身熵足够大(比如 32 字节=256 比特),这么做是安全的。
- 后者(问答题)的原理是,用答案加密一个 16 字节左右的随机数据。只有答案正确才能解密、获取到这个随机的参数。这里有个问题是,通过枚举可以猜出答案,导致不但问答题的意义丧失,还会暴露隐私。所以解决方法是,
- 首先用较大的 S2K 参数(类似 PBKDF 之类函数的作用,是 gpg 自带的一个功能),增加枚举的难度;
- 其次是,建议用户设置十分复杂不容易猜解的问题。比如如果猜生日,那么过去 10 年只有不到 3660 种可能。但是如果猜“身份证号+姓名”,就有更大的空间。
- (正在考虑中)设置一个全局的解密密码,首先控制对所有谜题和消息的解密,然后通过 URL 加
#的形式放置在通知邮件中。
所以说到底,本程序也不仅仅可以用来留这么悲伤的消息了。也可以把其他的需要读者证明自己身份的信息放进来。
要例行声明的是:
因所述的密码方案未必成熟,不要马上把这个程序拿来加密自己的留言!
(然而我会在感觉合适了之后自己就这么做的,嗯。)