通过智能卡来使用PGP

发布于 2020-12-14  9700 次阅读


通常使用PGP时,私钥都存储在本机,这就留下了泄漏的隐患。为了去除这种隐患,可以将私钥转移到单独的智能卡中。智能卡通常都无法从中提取私钥,需要私钥进行的操作都通过卡内的处理器来进行,从而降低了泄漏的风险。

这里使用的硬件为Yubikey,由于操作是通过GPG客户端来进行,所以即使是其他品牌的设备也不会有太大差别。需要注意的是确保密钥类型和长度需要符合卡的要求,否则无法写入或生成。

在使用时,可以选择直接生成私钥或者将已存在的私钥导入。由于私钥无法提取,所以不建议直接在卡中生成,如果需要在卡中生成的话,也应先生成并备份主密钥后再在卡中生成子密钥。

初始化智能卡

在初次使用时,通常需要先对卡进行编辑。插入智能卡,然后输入以下命令:

gpg --card-edit

执行后会返回卡的信息并进入编辑模式。接下来输入admin并回车来启用管理员命令。

输入help可以显示可执行的命令的帮助,注意在开启或关闭管理员命令后这个列表是不同的。首先输入passwd命令来进入PIN码设置模式。然后分别修改PIN、Admin PIN和Reset Code。要注意的是gpg卡的PIN码通常时允许输入字母的,而且Admin PIN不可少于8位。其中PIN码用于使用私钥、Admin PIN用于修改只能卡的信息、而Reset Code则用于在输错三次PIN时进行解锁。如果Admin PIN和Reset Code输错三次,则卡会锁定,只能使用制造商的设置软件来清空所有PGP信息进行出厂还原。

在PIN设置完毕后,输入q来退出PIN设置模式退出后可以继续设置姓名、公钥服务器的URL等等信息,设置完毕后,输入quit来退出编辑模式。

在智能卡中生成密钥

生成主密钥

首先,并不建议直接在卡中生成主密钥,如果执意要做,也应保留加密密钥的备份来避免设备损坏或丢失后无法解密的情况。

输入以下命令进入卡片编辑模式:

gpg --card-edit

然后输入admin命令来开启管理命令,之后输入generate命令进行生成。生成前会询问是否创建加密密钥的离卡备份。之后的过程和正常的生成的过程差别不大。过程中会额外要求智能卡的PIN码和Admin PIN码。

生成后会显示加密密钥备份和吊销证书的存放位置以及卡中的密钥,正常情况下,包括主密钥会生成三个密钥,分别放置于签名槽、加密槽和认证槽中。其中,签名密钥为主密钥,加密和认证为子密钥。

生成后返回的密钥列表中,会比不用智能卡时多出卡号一栏。

生成完成后输入quit保存并退出。

生成子密钥

和直接在卡上生成主密钥不同,在卡中生成子密钥应使用密钥管理命令:

gpg --edit-key 密钥名

使用然后输入addcardkey命令来在智能卡中生成子密钥。生成过程与正常区别不大,生成时需要输入Admin PIN、PIN以及主密钥的密码。

这里直接在卡内生成的加密密钥并不会询问和生成备份文件,所以不推荐用这种方式生成加密密钥。

完成后输入save保存并退出

导入密钥到卡中

从备份文件导入

通过备份文件导入的功能通常只适用于在卡中生成密钥时产生的备份文件,使用私钥导出的命令导出的子密钥并不能通过这个命令导入,而导出包括子密钥在内的全部私钥时,导入时则只能导入主密钥。

首先进入密钥编辑模式,然后使用以下命令导入:

bkuptocard 备份文件名

完成后输入save保存并退出。

转移私钥

在转移私钥前,先对私钥进行备份!

使用转移命令时,在转移后本机内的私钥会被删除,所以备份应在转移前进行。

备份后进入密钥编辑模式,如果要转移主密钥,则不选择任何子密钥并执行keytocard命令,然后选择要导入的槽位。

如果需要导入子密钥,则输入key 子密钥序号来选择转移的子密钥,一次转移只选择一个。选择后执行keytocard命令并选择要导入的槽位。

导入完成后输入save保存并退出。

转移之后私钥会被指向智能卡的存根取代,在使用时需要插入输入智能卡并输入PIN码才可以使用。

更换智能卡

由于gpg会绑定智能卡的编号,所以即使在另一张卡内写入相同的私钥也不能直接替换,所以需要重新绑定智能卡。

如果只有一个私钥,并且已经移动到智能卡内,可以通过删除gpg私钥文件并重新建立。

文件位于~/.gnupg/private-keys-v1.d(*nix)或%USERPROFILE%\AppData\roaming\gnupg\private-keys-v1.d(Windows)中,删除后插入卡并使用gpg --card-status命令重新绑定。

或者使用下列命令来使用当前插入的智能卡来更新私钥存根:

gpg-connect-agent“scd serialno”“learn --force”/bye