Serverless 应用示例:Serverless 密码管理器
最近的几年里,每个人在密码上都遇到越来越多的挑战,即需要一个复杂的密码,又需要能记得住它们——两者几乎不可兼得。于是乎,我们开始使用上各式各样的密码管理器,并为之付上了费。又或者是一些开源的、不能同步的密码管理工具——毕竟服务器是要钱的。
然而作为一个程序员,我觉得嘛,他/她们写的代码都不可靠——愈是通用的软件,愈加危险。一旦一个地方出现问题,那么其它地方都会有问题。比如说,你的 Master Password 泄露了,那么相应的所有的密码也就相当于泄露了。以致于我又重新设计了自己的密码管理体系,写了一个自己的密码管理器。
取个密码
取一个变量很纠结,取一个密码很头痛——更何况,我们要取一堆密码。于是,最好的方式就是写一个规则,来生成不同密码。从安全的角度来看,密码自然是又长又复杂的为好。可又复杂又长的代码,我们这些非机器的人是记不住的。
根据我的现有模式,我有这么几种模式来管理密码。
特定平台 + 固定密码
11 年前我使用一个固定的、统一的密码,直到一系列的明文密码泄露事件,我在不同的平台采用了不同的密码。在经历了一系列的忘记密码之后,我开始采用平台限定的密码,即不同的平台,密码是半动态的。如下就是一个简单的,对应于不同平台的代码体系,如:
- 京东:
jd-1qaz2wsx
- 淘宝:
tb-1qaz2wsx
而这样的密码本身也是不安全的,如果有人知道密码规则的话。那么,这无异于一场灾难。于是,我在设计出规则到现在,仅会在一些重要的网站上,采用这种规则。
密码表 + 特定平台 + 固定密码
应对于上一种方式,如果我们拥有一个密码表,来稍微变换一下形式,诸如:
- 京东:
tb-1qaz2wsx
- 淘宝:
jd-1qaz2wsx
那么,我们的密码就显得更加可靠。
随机密码 + 固定密码
如我们所知道的那样,只要是有规律的代码,都存在被破解的风险。所以在两年前,我写了一个简单的脚本来生成密码:
from random import choice
from string import hexdigits, punctuation
import time
base_time = str(time.time())[12:16]
base_string = ''.join(choice(hexdigits) for i in range(6))
base_punctuation = ''.join(choice(punctuation) for j in range(2))
print(base_string + base_punctuation + base_time)
从时间戳取四个数字,从 16 进制数中取出 6 位,再从特殊字符中取出两位,以此来构成我的密码的主要部分。而剩下的部分则是固定密码,固定的部分存在脑子里——万一密码都看到了,那么问题也不到。
唯一需要担心的是,键盘上的值可能被记住了。即,有人监听你的输入,又或者是记住了剪贴板上的值——从这个角度上来看,输入法也是一个危险的存在。为此,我们还需要更高级的工具。
密码管理器
使用密码管理器,毫无疑问是目前为止最为通用的一种方式,诸如 1Password 和 LastPass 都是相对比较成熟的方案。它们可以运行在各种平台上,相互之间同步代码,并帮你自动填充密码。
然而,这些工具都是按年付费的,部分还是私有软件。
开启 MFA
但是不管怎样,密码的方式仍然是相当的不可靠——一旦泄露了就悲剧了。为此,如果你所用的平台,可以开启 MFA,就开启 MFA 吧。即 Multi-Factor Authentication (MFA) 是一种简单有效的最佳安全实践方法,它能够在用户名和密码之外再额外增加一层安全保护。
Serverless 架构下的密码管理器:MoPass
要是我使用的是密码管理器的话,就没有本文的这么多事了。所以,我正在写自己的秘密管理器。
在编写我的第三本书的时候,同时编写了我的 markdown 编辑器:Phodit。Phodit 的成功实施,让我在定制个人工具上,有了更坚定的信心和丰富的经验,所以我开始编写我的密码管理器——基于 Serverless 架构的密码管理器。
系统的组件和关系相对都比较简单:
大抵就是对于密码的加解密和 CRUD,只是客户端有所不同罢了。
由于设计的初衷是:针对于个人的轻量级密码管理器,所以在最初设计的时候,是根据 Master Password + MD5 来生成后台的授权 Token。当用户数量变多的时候,Master Password 便会出现重复,导致密码重复的问题——由于使用了 Key + Master Password 来对密码进行加密和解密,虽然 Master Password 相同,但是也无法解密别人的密码。
在终端中使用 CLI
一个不习惯用命令行的程序员,不是一个高效的程序员。——Phodal
一个密码管理器,最好是直接输个命令就能获取了,而不是打开某个软件、输入密码、找到对应的条目,再复制密码。对于 MoPass 来说,获取密码,只需要这么一步:
➜ mopass git:(master) mopass --get GitHub
? master password ******
200: Copied to clipboard!
而后,我们就可以直接粘贴我们的密码——为了查看所有的条目,只需要 mopass --list
。从这等意义上来说,这个工具更适合于程序员使用。而为了使用更加方便,我还是写了一个 Chrome 上的插件——毕竟,输入密码的场景,主要是在网页上,而不是终端里——我可不习惯用 w3m 来浏览网页。
通过 Chrome 插件中使用
Chrome 插件,只需要输入密码即可——不过,为了安全考虑,不在浏览器上存储密码,而是每次从服务器上获取。这个问题,可以在我稍有余力的时候,再去看看怎么优化——毕竟 CLI 更快。
结论
最后,请不到你的密码贴在笔记本上。
GitHub: https://github.com/phodal/mopass