2个版本
0.0.2 | 2023年6月22日 |
---|---|
0.0.1 | 2023年6月15日 |
#2130在密码学
105KB
1K SLoC
openpgp-pkcs11-tools
该包实现了opgpkcs11
,这是一个探索性命令行工具,它将openpgp-pkcs11-sequoia中的功能暴露出来,以便在OpenPGP环境中使用PKCS #11设备。
该工具可用于将OpenPGP组件密钥上传到PKCS #11设备,并使用这些密钥执行OpenPGP签名和解密操作。
此工具还可用于将基于gnupg-pkcs11-scd的设置迁移到Sequoia PGP。在此用例中,需要OpenPGP公钥(或OpenPGP证书)以及PKCS #11设备(OpenPGP证书是访问HSM上不可用的OpenPGP元数据的必要条件)。
通过PKCS #11进行签名
一旦将签名子密钥加载到HSM中,就可以将其用作OpenPGP密钥进行签名(该工具生成一个分离的签名)。
$ echo "hello world" | cargo run --bin opgpkcs11 -- sign --serial 16019180 --id 2
-----BEGIN PGP MESSAGE-----
wsAdBAATCgBvBYJj9RTACRDgxC4SrzU3rkcUAAAAAAAeACBzYWx0QG5vdGF0aW9u
cy5zZXF1b2lhLXBncC5vcmcbgC3H5TAyHrskkS/Df1YhQm0hOxV2PR//4p0LHA7k
cRYhBNbjGCcsr64WE/F/t+DELhKvNTeuAABosAF/Yd26f75FMeP8uSVFR2+4J593
F+O5+U5kx1Fo1IXX6gNhrLuniEq7fDrbflFStbuCAX47Cd/+D/IlC6YSf//W9etl
sd4uMBq3AWNU3IwYJpm3/Zcx0L/2CTVa3hYa/jWmCm8=
=/R5+
-----END PGP MESSAGE-----
注意:在YubiKey 4/5上,--id 2
对应于PIV "数字签名"插槽(PIV 9c)。有关ykcs11密钥映射的更多信息,请参阅此处。
(如果您的系统上PKCS #11模块的默认路径/usr/lib64/libykcs11.so
不正确,您需要通过参数--module
提供路径。)
将此分离签名存储在/tmp/sig
后,我们可以使用sq进行验证
$ echo "hello world" | sq verify --signer-file /tmp/janus.pgp --detached /tmp/sig
Good signature from E0C42E12AF3537AE
1 good signature.
通过PKCS #11进行解密
类似于签名(上面),PKCS #11设备可以用于执行OpenPGP解密操作
让我们创建一条加密消息
$ echo "secret message!" | sq encrypt --recipient-file /tmp/janus.pgp > /tmp/secret.pgp
(如果您的系统上PKCS #11模块的默认路径/usr/lib64/libykcs11.so
不正确,您需要通过参数--module
提供路径。)
现在我们可以在卡上解密消息
$ cat /tmp/secret.pgp | cargo run --bin opgpkcs11 -- decrypt --serial 16019180 --id 3
secret message!
注意:在YubiKey 4/5上,--id 3
对应于PIV "密钥管理"插槽(PIV 9d)。有关ykcs11密钥映射的更多信息,请参阅此处(ID 5-24可用于访问"退役密钥管理"插槽)。
上传到PKCS #11
cargo run --bin opgpkcs11 -- upload --serial 1234 --id 2 --key /tmp/janus.rsa2 --fingerprint E35AE0F1494FBE1098014BD61E71CF45C4A31FEC
注意:由于ykcs11驱动程序的限制,当前通过ykcs11驱动程序将数据上传到YubiKey 4/5不可用(作为替代方案,可以通过PIV接口将这些OpenPGP密钥上传到这些设备,然后通过PKCS #11进行签名和解密)。
支持PKCS #11的硬件设备
有关可以通过PKCS #11访问的一些特定设备的说明。
YubiKey 4/5
https://developers.yubico.com/PIV/
- YKCS11模块(显示PIV到ykcs11 ID的映射)
使用YubiKey PIV CLI工具的示例设置
重置卡片上的PIV应用程序
$ykman piv reset
在槽位'9d'("密钥管理")中生成新密钥,并将公钥导出到文件public-9d.pem
$yubico-piv-tool -s9d -agenerate -AECCP256 -opublic-9d.pem
(要检查公钥ECC文件:openssl ec -pubin -in pubkey.pem -text
)
在槽位'9a'("PIV认证")中生成新密钥,默认使用RSA,并将公钥导出到文件public-9a.pem
$yubico-piv-tool -s9a -agenerate -opublic-9a.pem
PKCS #11访问的动态库
$export MODULE=/usr/lib64/libykcs11.so
检查卡片上的"对象"
$pkcs11-tool --module $MODULE -O
支持的功能和限制
YubiKey PIV小程序(可以通过PKCS #11接口可选访问)支持RSA 2048、NIST P-256和NIST P-384。支持使用这些算法的密钥进行签名和解密操作。
由于ykcs11驱动程序的限制,目前不支持通过PKCS #11接口上传到卡片。然而,可以使用PIV接口将密钥上传到卡片,然后通过PKCS#11进行加密操作。
注意
YubiHSM 2
https://developers.yubico.com/YubiHSM2/Usage_Guides/YubiHSM_quick_start_tutorial.html
USB访问(udev)
需要授权对USB设备的访问,例如使用以下udev规则
/etc/udev/rules.d/10-yubihsm.rules
:
SUBSYSTEM=="usb", ATTRS{idVendor}=="1050", ATTRS{idProduct}=="0030", OWNER="username"
如有必要,重新加载规则
# udevadm control --reload-rules
注意:在我的系统中,当连接到USB3端口时,YubiHSM2不起作用。如果遇到问题,请尝试不同的USB端口和/或USB集线器。
yubihsm-connector
"Connector,yubihsm-connector,负责YubiHSM 2与应用程序之间的通信"
https://developers.yubico.com/YubiHSM2/Component_Reference/yubihsm-connector/
$ yubihsm-connector -d
一旦连接器运行,可以通过以下方式测试对YubiHSM的访问
$ yubihsm-shell
Using default connector URL: https://127.0.0.1:12345
yubihsm> connect
Session keepalive set up to run every 15 seconds
注意:在正常操作期间,在我的系统中,我在yubihsm-connector
输出中看到常规错误:handle_events: error: libusb: interrupted [code -10]
登录
- https://docs.yubico.com/software/yubihsm-2/component-reference/hsm2-ref-pkcs11.html#logging-in
- https://docs.yubico.com/hardware/yubikey/yk-5/tech-manual/yubihsm-auth.html
默认情况下,使用yubihsm-shell
登录的方式如下
yubihsm> session open 1 password
在yubihsm-shell
中,使用KDF方案
列出对象
yubihsm> connect
Session keepalive set up to run every 15 seconds
yubihsm> session open 1 password
Created session 0
yubihsm> list objects 0 0 asymmetric-key
Found 12 object(s)
id: 0x02f1, type: asymmetric-key, algo: rsa2048, sequence: 0 label:
[..]
id: 0xf6bc, type: asymmetric-key, algo: rsa2048, sequence: 0 label:
重置YubiHSM
yubihsm> connect
Session keepalive set up to run every 15 seconds
yubihsm> session open 1 password
Created session 0
yubihsm> reset 0
Device successfully reset
通过PKCS #11使用YubiHSM2
https://developers.yubico.com/yubihsm-shell/yubihsm-pkcs11.html
https://github.com/Yubico/yubihsm-shell/blob/master/lib/yubihsm.c#L579
YubiHSM PKCS #11模块的源代码
https://github.com/Yubico/yubihsm-shell/tree/master/pkcs11
测试
yubihsm_pkcs11.so
可以使用配置文件。这里我们使用一个最小文件/tmp/ykhsm.conf
connector=http://localhost:12345
设置
$ export MODULE="/usr/lib64/pkcs11/yubihsm_pkcs11.so"
$ export YUBIHSM_PKCS11_CONF=/tmp/ykhsm.conf
$ export SERIAL=`cargo run --bin opgpkcs11 -- --module $MODULE list`
上传解密子密钥
cargo run --bin opgpkcs11 -- --module $MODULE upload --serial $SERIAL --slot dec --pin 0001password --key /tmp/janus.rsa
解密
echo "hello world" | sq encrypt --recipient-file /tmp/janus.rsa >/tmp/enc
cat /tmp/enc | cargo run --bin opgpkcs11 -- --module $MODULE decrypt --serial $SERIAL --pin 0001password
签名
echo "hello world" | cargo run --bin opgpkcs11 -- --module $MODULE sign --serial $SERIAL --pin 0001password
检查卡片状态
cargo run --bin opgpkcs11 -- --module $MODULE dump --serial $SERIAL --pin 0001password
支持的功能
支持所有操作(密钥上传、签名、解密)对于RSA 2048、RSA 3072、RSA 4096、NIST P-256、NIST P-384和NIST P-521。
PKCS #11的软件实现
SoftHSM2
https://github.com/opendnssec/SoftHSMv2
示例设置/使用
(当前Fedora的路径,在不同发行版上确切路径可能不同)
创建临时存储路径并配置SoftHSM使用它
$export SOFTHSM2_CONF=$(mktemp) && DIR=$(mktemp --目录) && echo "directories.tokendir =$DIR" > $SOFTHSM2_CONF
$export MODULE=/usr/lib64/softhsm/libsofthsm.so
在SoftHSM上初始化'槽0',设置用户PIN为123456
,在槽0生成RSA密钥
$ pkcs11-tool --init-token --module $MODULE --slot-index 0 --label TestToken --so-pin 12345678
$ pkcs11-tool --init-pin --login --so-pin 12345678 --pin 123456 --slot-index 0 --module $MODULE
$ pkcs11-tool --module $MODULE --slot-index 0 --login --pin 123456 --keypairgen --key-type rsa:2048 --id 3
检查卡片(需要用户PIN)
$pkcs11-tool --module $MODULE --test --pin 123456
使用SoftHSM测试opgpkcs11
"SoftHSM是通过PKCS #11接口访问的加密存储的实现。"
初始化(Fedora的模块路径,其他系统可能不同)
export SOFTHSM2_CONF=$(mktemp) && DIR=$(mktemp --directory) && echo "directories.tokendir = $DIR" > $SOFTHSM2_CONF
export MODULE=/usr/lib64/softhsm/libsofthsm.so
pkcs11-tool --init-token --module $MODULE --slot-index 0 --label TestToken --so-pin 123456
pkcs11-tool --init-pin --login --so-pin 123456 --pin 123456 --slot-index 0 --module $MODULE
生成用于测试的OpenPGP密钥
cargo run --bin janus_gen rsa2048 >/tmp/janus.rsa
将解密子密钥上传到SoftHSM
您可以使用以下命令将SoftHSM设备的序列号存储在环境变量SERIAL
中
export SERIAL=`cargo run --bin opgpkcs11 -- --module $MODULE list`
cargo run --bin opgpkcs11 -- --module $MODULE upload --serial $SERIAL --slot dec --key /tmp/janus.rsa
加密到密钥,在卡片上解密
echo "hello world" | sq encrypt --recipient-file /tmp/janus.rsa >/tmp/enc.janus
cat /tmp/enc.janus | cargo run --bin opgpkcs11 -- --module $MODULE decrypt --serial $SERIAL
支持的功能
在此设备上,所有操作(密钥上传、签名、解密)均支持以下算法:RSA 2048、RSA 3072、RSA 4096、NIST P-256、NIST P-384和NIST P-521。
在cli/ci/softhsm
下的CI测试测试所有支持算法的全部操作集。
依赖项
~31-42MB
~751K SLoC