网络越来越发达,各式各样的网盘、云存储也走进日常生活,我也开始在 DropboxGitHub 中存储一些个人文件和代码。隐私问题比较麻烦,会有一些特别隐私的信息(比如银行密码、心情日记等)是不适合直接存放在云端的。但又确实想要借助云平台的便利性,就必须要做加密处理。操作的方法很多,今天我说一下用 Git 来保存这些隐私信息。

等等,你说什么?还有 115 网盘、百度云盘、金山快盘等等国内知名云存储,空间又大、速度又快、功能又强。如果你这么觉得,那么再见,bye bye,さようなら。

我是不会用国内的云存储存放任何个人相关的东西的,最多放少量的网上下载的图书视频软件之类的。

好吧,言归正传,说咱们的加密。

当然你可以用虚拟加密磁盘(比如 TrueCrypt)之类的工具,或者直接用设置了密码的压缩包(我之前就是这么干的),但是在用起来都还是有些麻烦。比如我那些打了加密压缩包的东西,我就懒得再去看了,尤其懒得修改,实在太麻烦了。

我选择用 Git 来保存个人文档的另一个原因是,可以方便地进行版本控制,尤其如果需要在不同的电脑上进行操作,又难以完全实时进行同步的话。而且今天介绍的这个方法可以透明地对指定文件进行加密和解密(transparent encryption),也就是你在本地操作的时候根本不需要每次阅读前都解密,做了修改之后还要再做加密处理。工具会保证最终存在云端的那份是妥善加密的。

找到了两个实现此功能的工具,分别是

分别是用 C++ 和 Shell 写的。最后我选择了后者,当然以后也许会改变,反正加密解密算法跟工具是分离的,换工具并不会带来太多问题。

简单介绍一下如何使用,更准确的操作方式就直接去看项目的官方文档好了。

首先安装,我选择的 git-encrypt 是用 Shell 写的,所谓安装就是 clone 一下它的 repo,建立一个符号链接使得通过 $PATH 可以找到它即可。当然,你的系统中必须安装了 OpenSSL,它是加密解密的核心啊。

项目中有两个脚本文件,我只用其中的“gitcrypt”,另一个感觉不太好用。

假设云端存储用 Dropbox,在本地对应的目录是 ~/dropbox。(以下操作都是针对 Linux 平台的,Windows 的话可以去看一下官方文档)。先进入 dropbox 目录并创建一个新的 git 仓库(如果没有一个现成的):

1
2
3
4
cd ~/dropbox
mkdir myrepo.git
cd myrepo.git
git init --bare

这个仓库将会被同步到云端,任何提交到该仓库的隐私信息都应该是被加密过的。当然千万不要把密钥也存在这里。

然后去工作目录,比如叫 ~/personal,创建一个本地仓库(或者从 dropbox 中 clone 一个过来):

1
2
3
4
cd ~/personal
mkdir myrepo
cd myrepo
git init

然后就要做好加密解密的准备工作了,直接在本地仓库的根目录运行 gitcrypt init 命令,根据提示输入相应的信息。它首先会问你是否需要生成一个随机的 salt 值和密码,你可以同意或拒绝,拒绝的话就自己提供 salt 值和密码。如果你只有这个本地仓库,那建议直接使用随机生成的,那样足够复杂,更安全些。如果还需要在别的机器上 clone 这个仓库,那还是自己设置一下,免得忘了密码。然后选择加密算法,默认的是 aes-256-ecb(ECB 加密模式比较简单,相对容易破解,推荐使用 aes-256-cbc;当然 OpenSSL 提供了很多加密算法,大家可以自行选择;另外,发现一篇很直观的文章,可以看看,分组对称加密模式)。接下来会问你是否使用 .git/info/attribute,选择是就好了。最后问你需要对什么文件进行加密,默认是 * 表示所有文件。你可以根据需要进行设置,比如我这里让它加密所有以“private-”开头的文件,就输入 private-*

好了,完成了。接下来就正常地在仓库里提交各种文件,但只要文件名是以“private-”开头的,都会被加密后再被提交。

有一点要提一下,前面设置的 salt 值和密码,都是明文存储在 .git/config 中的,如果你的本地仓库也不那么安全的话,就牢记这两个信息,并在不需要的时候把仓库或者这个信息删掉,等到下次要用的时候再加上。

假设我创建两个文件,分别叫做 diary.txtprivate-diary.txt。其中后者是绝对不想让别人看到的。假设内容分别如下:

1
2
3
4
5
6
$ cat diary.txt
今天天气不错,挺风和日丽的。
我心情也还好,没有什么烦心事。
$ cat private-diary.txt
一点儿都不开心,那个人烦死了,老骚扰我。
我想暴走啊,想暴走。

好,然后将这两个文件都提交到仓库中,并将修改推到云端:

1
2
3
4
git add *.txt
git commit -m 'Add some diaries.'
git remote add origin ~/dropbox/myrepo.git
git push origin master

有人会问,不对啊,还没给私密日记加密啊。好,我们来把云端仓库再 clone 一份看看。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
$ git clone ~/dropbox/myrepo.git ~/personal/myrepo2
$ cd ~/personal/myrepo2
$ ls
diary.txt  private-diary.txt
$ cat diary.txt
今天天气不错,挺风和日丽的。
我心情也还好,没有什么烦心事。
$ cat private-diary.txt
U2FsdGVkX1/lfLd83fEEk8Gnaiixe5hdSPR7qgP+SFD9PSX6yNSX8osvd73gKqQG
Q4ndGa6A0RAuClmMO1E5tRnxKhk2jIHmiR6qyGKjx73BR2164PHnf3NioZM0tN25
88FtrD+Mqhq+b3MEsXLu2A==

可见,如果别人 clone 了你的云端仓库,他也只能看到加密后的信息。

如果这份 clone 的主人也是你,你现在想在这里查看或者修改你的文档,只要再运行一次 gitcrypt init,输入同样的 salt 和密码,保持其它设置也都一致,最后再运行一次 git reset --hard HEAD 就好了。

1
2
3
4
5
6
7
$ gitcrypt init
blah blah (use the exact same configuration)
$ git reset --hard HEAD
HEAD is now at 10c8613 Add some diaries.
$ cat private-diary.txt
一点儿都不开心,那个人烦死了,老骚扰我。
我想暴走啊,想暴走。

关于 salt 和密码。解密的时候只要有密码就够了,加密的时候则需要同时提供 salt 和密码。用 salt 一方面可以在密码太简单的情况下加大破解难度(参见 Rainbow table),另一方面使用相同的 salt 可以让每次加密得到的密文是一致的。如果你在第二次 clone 后改用不同的 salt,并不会影响密文的解密,但是 git 会认为那些文件被修改了,而 diff 的时候去看不到任何差异。我觉得这个不太合理啊,期待这个工具的更新。

最后,一些关于 transparent git encryption 的讨论:

当然也有反对的声音,所以建议大家先多了解了解再决定要不要使用这个方法。

Like this post? Share on: TwitterFacebookEmail

Comments

So what do you think? Did I miss something? Is any part unclear? Leave your comments below.

comments powered by Disqus

Published

Category

有用知识

Tags

Stay in Touch