椭圆曲线(ECC)支持

RSA-2048变得越来越不安全了

出于安全考虑,德国联邦信息安全办公室(Bundesamt für Sicherheit in der Informationstechnik, BSI)不再建议在2023年之后使用长度为2048位的RSA密钥` <https://www.bsi.bund.de/SharedDocs/Downloads/EN/BSI/Publications/TechGuidelines/TG02102/BSI-TR-02102-1.pdf>`__。这意味着在可预见的未来,更长的密钥将需要投入使用。假设使用期为5年,已经有必要产生更长的密钥了。然而,3072位或4096位的较长RSA密钥的速度明显较慢。由于这个原因,新的Nitrokey Storage 2和Pro 2(即集成的OpenPGP卡3.3版)支持通过`椭圆曲线加密法(ECC)<https://en.wikipedia.org/wiki/Elliptic-curve_cryptography>`__加密。这种方法被认为是用较小的ECC密钥和较长的RSA密钥一样安全,而且速度也相当快。

椭圆曲线加密法的基础知识

与RSA相比,椭圆曲线加密法有许多不同的形式(所谓的曲线)。值得注意的是,`NSA参与了<https://www.schneier.com/essays/archives/2007/11/did_nsa_put_a_secret.html>`__在NIST曲线的开发。即使没有证据表明曲线中存在后门,使用某种曲线也会带来信任问题。幸运的是,新的Nitrokey Storage 2和Pro 2支持两种曲线,即NIST和Brainpool。在下面的内容中,我们将使用Brainpool 曲线。`这篇文章<https://arstechnica.com/information-technology/2013/10/a-relatively-easy-to-understand-primer-on-elliptic-curve-cryptography/>`__为获得对椭圆曲线加密法的一般理解提供了一个很好的切入点。

系统要求

为了创建基于椭圆曲线的钥匙,需要Nitrokey Storage 2 / Pro 2和GnuPG 2.1.17版或更高版本。

你可以通过``gpg2 --card-status``读取Nitrokey的OpenPGP卡版本。

> gpg2 --card-status
Reader ...........: 20A0:...
Application ID ...: D276...
Version ..........: 3.3
...

版本 "字段表示集成在Nitrokey中的OpenPGP卡的版本--在这种情况下,它是3.3,因为椭圆曲线加密法需要。OpenPGP卡2.2版本不支持ECC。

你可以通过``gpg2 --version``了解GnuPG的安装版本。至少需要2.1.16版本。最新的Windows版GnuPG可以在`这里<https://www.gpg4win.org/>`__,最新的MacOS版可以在`这里<https://gpgtools.org/>`__找到。GNU/Linux发行版Ubuntu(从18.04开始)、Debian(从Stretch开始)、Arch Linux、Fedora(从26版开始)和openSUSE Tumbleweed中都包含了合适的GnuPG版本。在这篇文章的末尾,有如何在旧版Ubuntu上手动更新GnuPG的说明。

重要

GnuPG 2.0仍在使用,但对它的支持已在2017年停止。所有通信伙伴必须使用GnuPG 2.1或更新版本,通过ECC进行电子邮件加密,否则可能出现不兼容问题。因此,你应该只使用ECC,如果你确定你将能够规避这个问题。

在Nitrokey Storage 2 / Pro 2上生成钥匙

一旦这些要求得到满足,你就可以开始了。(警告:现有的钥匙在这个过程中会被覆盖!)你现在有两个选择。第一个选择是直接在Nitrokey Storage 2 / Pro 2上创建钥匙。这样做的好处是,钥匙将永远不会在设备之外,因此永远不会被读出。第二个选择是导入以前在本地生成的密钥。这种情况的好处是,你可以安全地存储钥匙的备份,一旦硝基钥匙丢失,就可以恢复。下面只介绍第一个选项。为了创建一个带备份的钥匙,你可以访问`下面的说明<https://www.gniibe.org/memo/software/gpg/keygen-25519.html>`__并使用这个`一般信息<https://wiki.fsfe.org/TechDocs/CardHowtos/CardWithSubkeysUsingBackups>`__将钥匙转移到Nitrokey上。

在GnuPG中,已经有一个 "生成 "命令,可以用来在设备上轻松地创建钥匙。但是,目前还不能直接选择钥匙的类型,所以必须首先准备好钥匙。我们使用以下命令来实现这一点。

> gpg-connect-agent "SCD SETATTR KEY-ATTR --force 1 19 brainpoolP256r1" /bye
> gpg-connect-agent "SCD SETATTR KEY-ATTR --force 2 18 brainpoolP256r1" /bye
> gpg-connect-agent "SCD SETATTR KEY-ATTR --force 3 19 brainpoolP256r1" /bye

另外,也可以选择其他曲线,如下一节所述。

现在我们输入``gpg2 --card-edit``,看到brainpoolP256r1在 "密钥属性 "下而不是rsa2048。

> gpg2 --card-edit
Reader ...........: 20A0:4109:0000000000000:0
Application ID ...: D276000124010303000500005F100000
Version ..........: 3.3
Manufacturer .....: ZeitControl
Serial number ....: 00005F10
Name of cardholder: [not set]
Language prefs ...: [not set]
Sex ..............: unspecified
URL of public key : [not set]
Login data .......: [not set]
Signature PIN ....: forced
Key attributes ...: brainpoolP256r1 brainpoolP256r1 brainpoolP256r1
Max. PIN lengths .: 64 64 64
PIN retry counter : 3 0 3
Signature counter : 0
Signature key ....: [none]
Encryption key....: [none]
Authentication key: [none]
General key info..: [none]

然后我们创建密钥。

gpg/card> admin
Admin commands are allowed

gpg/card> generate
Make off-card backup of encryption key? (Y/n) n
Please note that the factory settings of the PINs are
PIN = '123456' Admin PIN = '12345678'
You should change them using the command --change-pin
Please specify how long the key should be valid.
0 = key does not expire
<n> = key expires in n days
<n>w = key expires in n weeks
<n>m = key expires in n months
<n>y = key expires in n years
Key is valid for? (0)
Key does not expire at all
Is this correct? (y/N) y
GnuPG needs to construct a user ID to identify your key.
Real name: Jane Doe
Email address: jane.doe@example.org
Comment:
You selected this USER-ID:
"Jane Doe <jane.doe@example.org>"
Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? O
gpg: key 7F8C68E1B084E169 marked as ultimately trusted
gpg: revocation certificate stored as '/home/jane/.gnupg/openpgp-revocs.d/F8C00BC1636A7D7604A31A877F8C68E1B084E169.rev'
public and secret key created and signed.

Nitrokey现在采用了椭圆曲线加密法,而不是RSA密钥,可以照常使用。

可用的曲线

在上述程序中,我们选择了Brainpool的曲线。另外,也可以使用NIST曲线。配置工作按以下方式进行。

> gpg-connect-agent "SCD SETATTR KEY-ATTR --force 1 19 nistp256" /bye
> gpg-connect-agent "SCD SETATTR KEY-ATTR --force 2 18 nistp256" /bye
> gpg-connect-agent "SCD SETATTR KEY-ATTR --force 3 19 nistp256" /bye

Ubuntu上GnuPG的更新

只有当你运行的Ubuntu版本超过18.04时才需要以下步骤。你可以用下面的命令在这种系统上安装GnuPG 2.1.18。这涉及到较新的Debian软件包,这是最简单的选择。这种方法已经在Ubuntu 17.10上测试成功,可能在16.04上也适用。然而,不能排除在使用过程中出现问题的可能性。

$ mkdir gnupg_tmp
$ cd gnupg_tmp
$ wget http://ftp.debian.org/debian/pool/main/g/gnupg2/gnupg_2.1.18-8~deb9u1_amd64.deb
$ wget http://ftp.debian.org/debian/pool/main/g/gnupg2/dirmngr_2.1.18-8~deb9u1_amd64.deb
$ wget http://ftp.debian.org/debian/pool/main/g/gnupg2/gnupg-agent_2.1.18-8~deb9u1_amd64.deb
$ wget http://ftp.debian.org/debian/pool/main/g/gnupg2/scdaemon_2.1.18-8~deb9u1_amd64.deb
$ sudo dpkg -i *
$ cd ..
$ rm -rf gnupg_tmp

如果你想撤消安装,你必须执行以下命令。

$ sudo dpkg --remove --force-depends gnupg dirmngr gnupg-agent scdaemon
  # (removes manually installed packages)
$ sudo apt-get install gnupg dirmngr gnupg-agent scdaemon
  # (installs the appropriate packages from regular package repositories)