场景和原理
在我们的日常工作中,经常会有需要在内部和外部直接进行文件交换的需求。比如通过QQ、微信、电子邮件附件等等。 但大多数普通人,并没有很好的信息安全意识,很多文件就直接发送和传输了,造成了很大的信息泄露和安全风险。
有的人稍微好点,安全意识和工具使用能力较强,就知道把文件打个包,同时使用密码保护一下。或者对于Office和pdf文件,使用编辑工具设置一个密码。一般而言,比较新的软件都使用了诸如AES等先进的加密算法来进行保护,这一点是没有太大的问题的。主要的问题在于密码的管理和交换,因为为了方便,他们通常不会使用太复杂的密码,另外,他们可能会使用短信或者其他聊天工具,把密码告诉接收文件的人,其实这个环节,才是整个流程中最大的安全漏洞。它会造成几个主要问题:
- 加密的安全和强调,取决于密码的复杂性,但会牺牲方便性
- 文件本身的安全可以受到加密算法和密码的保护,但密码本身的交换和传输,可能存在漏洞
- 使用密码的另外一个问题,在于如果密码泄露,使用密码的人并不知道这个情况,任何拿到密码和文件(加密文件也可能是在公开渠道上传输的)的人,都有机会和能力来解密文件,而不为加密者所知
- 解密的人,其实也无法确认这个信息就是由加密者提供的
这些问题看起来比较麻烦,但实际上,在技术上已经有比较完善的解决方案。但遗憾的是,由于认知和使用习惯的问题,应用的并不普遍。简单而言,就是使用非对称(公私钥加密)加密技术,从密码学技术的角度出发,这个问题可以这样解决:
- 交换信息的双方(我们称为Charlie和Steven),分别各自生成一对公钥和私钥
- 私钥必须由个人私下保存(还可以使用密码加密),不能分享
- 公钥可以公开,比如可以放在网站上,或者电子邮件传输,当然最安全的方式是当面交给对方并且验证
- 双方交换或者使用某种方式获取对方的公钥
- 如果Charlie要向Steven发送信息,可以使用Steven的公钥进行加密,然后将密文传送给Steven
- 同时Charlie可以使用自己的私钥,对信息进行签名
- Steven收到信息后,使用自己的私钥对信息进行解密(因为是Charlie使用匹配的公钥加的密)
- 同时Steven还可以使用Charlie的公钥,对信息进行签名,从而确认这个信息确实来自Charlie
- 在这个过程中,其实信息也是使用一个密钥进行加密的,但这个密钥并不需要进行传递,因为它是通过自己的私钥和对方的公钥协商计算出来的,算法可以保证其安全性
大致的流程如下图所示:
GPG
GPG就是基于前面描述的非对称加密技术,开发的通用文件和信息加密软件套件。GPG(GNU Privacy Guard, GNU 隐私保护程序)是RFC4880定义的OpenPGP标准的一个完整的实现,而且是遵循GNU开源协议的自由软件。GPG内置多种密钥管理系统,支持多种公钥目录,可以依此对数据和通信进行加密和签名,来保护信息安全和隐私。GPG也提供了对S/MIME和SSH的支持,可以用于安全的电子邮件和远程访问终端。
在类Unix和Linux系统中,通常使用命令行来操作和使用GPG。在Windows系统中,可以使用其Windows实现版本- GPG4Win。
一般流程
我们从一个实际的文件加密、传输和解密的使用流程和场景出发,来了解一下GPG使用的一般流程。
Charlie有一个文件需要传输给Steven;他需要使用GPG来保证这个过程的安全。
- steven安装GPG软件
Charlie告知Steven,需要他的公钥和GPG来对文件进行加密,这时候Steven没有GPG软件,也没有公钥,他需要先安装一个。Steven使用的是Windows操作系统,所以他先到GPG4Win网站上,下载并安装了GPG4Win软件。
安装完成后,steven就可以使用GPG来进行下一步工作了。可能是由于移植的原因,GPG4Win的安装和普通的Windows程序不一样,它会在Program Files目录下建立GPG目录和GPG4Win目录,也就是说,其实它保留了全套的GPG命令行工具;另外,它提供了相关的Windows GUI工具,来提供Windows程序的体验。实际上,我们日常使用的核心GUI程序名为Kleopatra(不是你想象的gpg4win.exe)。
- steven生成公钥
安装完成后,他需要生成他的公钥和私钥对。在开始菜单中启动Klopatra。在程序"文件"菜单中选择新建密钥对,输入属主名称、电子邮件地址和密码(可选)可以创建这个密钥对。创建成功后,会出现在密钥列表中。
在高级设置中,我们可以看到GPG可以使用ECDSA\ECDH和ed25519等先进的椭圆曲线非对称加密技术。
- steven导出和发布公钥
steven可以直接将公钥导出,然后发给clarlie。但为了以后使用的方便,他还可以将其公钥发布到公钥目录中(使用菜单"在服务器上发布"),这样任何人都可以检索并使用他的公钥,来给他发送加密的文件和信息了。发布成功后,steven就可以不需要将公钥导出发送给charlie,而直接告诉charlie他已经将公钥发布,而且使用其电子邮件地址(生成时使用的)就可以搜索了。
这里有一个问题是,GPG支持标准的公钥目录服务,所以,不同的GPG程序,它们可能使用的是不同的目录服务器地址。所以steven可能还需要将目录服务地址告诉charlie,这里是(程序安装默认,可以在设置中看到):
hkps://keyserver.ubuntu.com
- Charlie安装和配置GPG
在加密操作之前,Charlie也要按照GPG软件,他使用Debian系统,可以使用apt命令来安装GPG。 然后使用GPG命令来使用GPG的相关功能。GPG的主程序只有一个,所有功能都是通过参数进行设置。笔者高度怀疑,GPG4Win的核心也是这个主程序,然后套了一个Windows界面方便菜单操作而已。
// 安装```
sudo apt install gpg
// 生成密钥
gpg --full-generate-key
// 查看当前密钥
gpg --list-secret-keys
gpg --list-public-keys
- charlie导入steven的公钥
charlie可以使用命令行,在目录服务器上搜索并且导入steven的公钥。
gpg --keyserver hkps://keyserver.ubuntu.com --search steven@live.com
gpg: data source: https://162.213.33.9:443
(1) steven <steven@live.com>
263 bit EDDSA key 7491D41AFEFC468F, created: 2023-05-26
Keys 1-1 of 1 for "steven@live.com". Enter number(s), N)ext, or Q)uit > 1
gpg: key 7491D41AFEFC468F: "steven <steven@live.com>" not changed
gpg: Total number processed: 1
gpg: unchanged: 1
--keyserver 用于设置命令使用的公钥目录服务器
--search 用于搜索公钥并且导入
--rev-keys 用于直接根据密钥ID来导入密钥
- charlie加密文件
导入公钥后,charlie可以使用steven的公钥,来对文件(这里是tosteven.txt)进行加密:
gpg --encrypt -r steven@live.com tosteven.txt
gpg: 632C342197D202B2: There is no assurance this key belongs to the named user
sub cv25519/632C342197D202B2 2023-05-26 steven <steven@live.com>
Primary key fingerprint: 92EE 058F DDB3 AF6F CB2F 0D22 7491 D419 FEFC 468F
Subkey fingerprint: B995 12E3 D450 83A7 81F4 5E1F 632C 3421 97D2 02B2
It is NOT certain that the key belongs to the person named
in the user ID. If you *really* know what you are doing,
you may answer the next question with yes.
Use this key anyway? (y/N) y
cat tosteven.txt.gpg
�^c,4!���@�>���{��"��� Ͻ�%j��nh =0V '���� ��E4|b#e+�o��Rh��Be*'�5
�=j!�[]��(F*/�U�6�up�k�1
^�R�(���8~�-�Ԇ��d��'[8��w��o56��9��o���d
D��J���7FS�E���[�
可以使用的参数包括:
--encrypt 加密文件
--sign 可选,使用私钥签名
-r 指定要使用的公钥(emailt形式)
如果一切顺利的话,这个指令,会在当前文件夹下生成一个tosteven.txt.gpg的文件,内容就是密文(直接看到的是乱码)了。这样charlie就可以使用任意方式,将这个文件发送给steven。
- steven解密文件
steven获得加密文件后,可以使用自己的私钥进行解密。同时如果这个文件是带charlie的签名,并且steven已经导入了charlie的公钥的话,还可以用这个公钥对这个文件进行验证,来确保这个文件确实是来自charlie的。
steven还是使用kleopatra程序,工具栏上的"解密/校验"打开这个文件,先校验,然后保存,大概是这样的:
打开解密后的文件,就可以查看原始内容:
从而完成了一个比较完整的密钥生成-分享公钥-加密信息-验证和解密信息的业务流程。
其他事项
可以看到,GPG的应用是比较简单方便的。其实GPG还有很多强大的功能和安全设置,可以使用。这里简单例举一下,读者有兴趣可以深入研究使用。
- 公钥认证和吊销
用户可以使用程序或者命令行,手工对公钥进行认证,后续在操作时,可以消除未认证的警告信息。也可以手动吊销某个公钥。
- 私钥加密
在生成密钥对的时候,可以选择设置使用密码来保护这个私钥,这样在每次使用私钥的时候,都需要进行用户交互来进行解密,进一步提高了密钥使用的安全性。
- 私钥备份
私钥应当非常私密的进行保管。也应该可以选择将其备份起来,避免由于系统故障而导致私钥的丢失或者破坏,影响解密操作。GPG工具提供了将私钥进行导出和备份的选项。
- 加密/签名消息
除了加密文件之外,Kleopatra还直接提供了一个加密记事本功能,可以直接对一段文本进行加密和签名;接到别人传来的加密消息时,也可以在这里进行解密和验证。这样,在聊天软件和电子邮件文本中,使用更加方便。
加密信息:
加密后的信息:
解密和验证:
- 密钥目录服务
GPG可以设置公钥目录服务器地址(默认地址是 hkps://keyserver.ubuntu.com)。 还支持x.509类型的目录服务(如微软的活动目录)作为公钥服务,这应该是给企业环境中使用的。
- 智能卡
GPG支持多种硬件智能卡,从而提供硬件级别的安全性和使用方便性。使用智能卡,密钥保存和相关密码学操作,都在智能卡内完成,可以脱离操作系统和文件系统,而且密钥的使用也单一并且完全可控的,还有自毁机制,这些特性都提供非常高的安全性。