Serverless 应用示例:Serverless 密码管理器

优质
小牛编辑
131浏览
2023-12-01

最近的几年里,每个人在密码上都遇到越来越多的挑战,即需要一个复杂的密码,又需要能记得住它们——两者几乎不可兼得。于是乎,我们开始使用上各式各样的密码管理器,并为之付上了费。又或者是一些开源的、不能同步的密码管理工具——毕竟服务器是要钱的。

然而作为一个程序员,我觉得嘛,他/她们写的代码都不可靠——愈是通用的软件,愈加危险。一旦一个地方出现问题,那么其它地方都会有问题。比如说,你的 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 架构的密码管理器。

MoPass C4 Context
MoPass C4 Context

系统的组件和关系相对都比较简单:

MoPass C4 Container
MoPass C4 Container

大抵就是对于密码的加解密和 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