pass 内置了上传与获取git仓库数据的指令,且官方在教程中也推荐把 .password-store 提交到github,这不禁让人疑惑:"这样真的安全吗?"

确实, .password-store 位于用户 HOME 目录下,是用户使用 pass 时存储所有密码的文件夹,暴露出去在直观上的确感觉很不安全,令人担忧。

但是, .password-store 中所有密码都是通过 gpg 加密的,只要 .password-store 中的数据不足以破解密文,那么用户的所有密码数据都是安全的!

.password-store 中的数据并没有直接记录任何加密用的密钥信息,pass 和 gpg 的配合方式保证了这一点。

pass 依赖于 gpg 工作!

gpg 能为我们生成gpg私钥和公钥,公钥用于加密文件,而私钥用于解密相应公钥加密的文件。

而 pass 是一款强依赖于 gpg 的软件, pass init <gpg-id> 并不会自动帮我们调用 gpg 生成gpg私钥与公钥,它只不过是将 gpg-id 记录在了 .password-store/.gpg-id 文件夹中:

1
2
3
4
$ pass init m12345@gmail.com
Password store initialized for m12345@gmail.com
$ cat ~/.password-store/.gpg-id
m12345@gmail.com

当 pass 进行对密码的加密时,会读取 .password-store/.gpg-id 中的记录的 gpg-id ,将其作为参数调用 gpg 进行加密。

因此如果在 gpg 的数据库中没有 gpg-id 这个用户及其密钥,那么 pass 将无法工作:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
$ gpg --list-key

pub rsa4096 2017-12-29 [SC]
33K1GDD22BC23KSA231KLJ37893DDDDAAAAAAAAA
uid [ultimate] Mephis Pheies (GPG OF TESTER) <m12345@gmail.com>
sub rsa4096 2017-12-29 [E]

$ pass init 2277669955@qq.com

Password store initialized for 2277669955@qq.com

$ pass insert test/tester

Enter password for test/tester:
Retype password for test/tester:
gpg: error retrieving '2277669955@qq.com' via WKD: Operation timed out
gpg: 2277669955@qq.com: skipped: Operation timed out
gpg: [stdin]: encryption failed: Operation timed out
Password encryption aborted.

这就是是为什么 .password-store 可以直接用 git 管理并上传到 github 的原因:pass 里面没有保存任何gpg密钥数据。