惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

AI
AI
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
D
Docker
Last Week in AI
Last Week in AI
Apple Machine Learning Research
Apple Machine Learning Research
WordPress大学
WordPress大学
F
Full Disclosure
博客园 - 【当耐特】
博客园 - 司徒正美
V
Visual Studio Blog
F
Fortinet All Blogs
T
Tor Project blog
T
Threatpost
Blog — PlanetScale
Blog — PlanetScale
月光博客
月光博客
C
Cyber Attacks, Cyber Crime and Cyber Security
阮一峰的网络日志
阮一峰的网络日志
GbyAI
GbyAI
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
T
Tenable Blog
M
MIT News - Artificial intelligence
L
Lohrmann on Cybersecurity
P
Palo Alto Networks Blog
I
Intezer
Stack Overflow Blog
Stack Overflow Blog
The Register - Security
The Register - Security
The Last Watchdog
The Last Watchdog
S
Securelist
T
Tailwind CSS Blog
V
Vulnerabilities – Threatpost
U
Unit 42
博客园 - 叶小钗
P
Proofpoint News Feed
C
Cybersecurity and Infrastructure Security Agency CISA
H
Help Net Security
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
酷 壳 – CoolShell
酷 壳 – CoolShell
Hacker News - Newest:
Hacker News - Newest: "LLM"
NISL@THU
NISL@THU
J
Java Code Geeks
H
Hackread – Cybersecurity News, Data Breaches, AI and More
SecWiki News
SecWiki News
www.infosecurity-magazine.com
www.infosecurity-magazine.com
Project Zero
Project Zero
T
The Exploit Database - CXSecurity.com
TaoSecurity Blog
TaoSecurity Blog
A
Arctic Wolf
Martin Fowler
Martin Fowler
T
Threat Research - Cisco Blogs
N
News | PayPal Newsroom

Liups233の小站

通过 WKD / OPENPGPKEY DNS 记录部署 GPG 公钥 - Liups233の小站 OpenLiteSpeed 安装与建站配置 详细教程 - Liups233 使用 DNSCrypt-Proxy 为 Linux 配置加密 DNS - Liups233 WordPress 7.0 编辑器改回无衬线字体 - Liups233の小站 Redis 数据库权限与 Unix Socket 配置 - Liups233の小站 Cloudflare 设置 mTLS 验证来源拉取 - Liups233の小站 Docker 自建 RustDesk 远程和 API 服务 - Liups233の小站 ChatGPT Go 印度区免费试用白嫖 1 年 - Liups233の小站 使用 S/MIME 证书签名并加密电子邮件 - Liups233の小站 为 WordPress 外发邮件添加 S/MIME 签名 - Liups233の小站 网站域名变更迁移教程/记录 - Liups233の小站 将动漫视频刻录为视频光盘-蓝光/AVCHD DVD - Liups233の小站 百乐 CUSTOM 912 钢笔使用体验 - Liups233の小站 使用 Cloudflare mTLS 用户端凭证保护博客登入页面 - Liups233の小站 Kobo 手动安装 NickelMenu 和 KOReader - Liups233の小站 Kobo 阅读器字典缺字解决 - Liups233の小站 iCloud+ 域名邮箱的注册和使用 - Liups233の小站 9 美元一年的通配符 SSL 证书 - Liups233の小站 宝塔面板 Nginx 启用 Brotli 和 Pagespeed - Liups233の小站 拷贝 DVD/Blu-ray 光盘并使用 MeGUI 压制 - Liups233の小站 Spotify 相较 Apple Music 的优点 - Liups233の小站 欧卡/美卡自定义手排挡位布局 - Liups233の小站 内地居民到港开户汇丰和中银香港全过程 - Liups233の小站 给光驱刷入 LibreDrive 固件解锁区域和加密限制 - Liups233の小站 个人博客适用的 Cloudflare 防火墙和缓存规则 - Liups233の小站 为Kobo阅读器添加Google Drive和Dropbox功能 - Liups233の小站 百乐 PILOT Capless Fermo 钢笔评测 - Liups233の小站 业余无线电 B 类考试笔记 - Liups233の小站 黑白阅读器的绝唱?Kobo Clara BW 简单评测 - Liups233の小站 八重洲 WIRES-X 网络注册与使用教程 - Liups233の小站 异世的同路人 — 恋语 Juliamo 游戏简评 - Liups233の小站 欢迎加入我的 FreeDMR 服务器 - Liups233の小站 低至 6 港币一年的 Club SIM eSIM 保号卡 - Liups233の小站 H310/H710(P)/H810 阵列卡刷写为直通模式 - Liups233の小站
YubiKey OpenPGP 智能卡使用指南 - Liups233の小站
Liups233 · 2026-06-22 · via Liups233の小站

前言

最近开始重新折腾 YubiKey,还挺有意思的,不过确实也不简单,特别是作为 OpenPGP 智能卡。本文会讲述如何设置和使用 YubiKey 的 OpenPGP 功能,以及生成密钥的推荐方法和注意事项,顺便也能让我记得密钥到期后知道怎么做(记性差)。

一般来说,对于 OpenPGP 功能,一个 YubiKey 就够了,所以本文不会涉及到密钥的备份,具体原因后面也会说。但如果你也需要用 FIDO2 等,还是建议买两个。我是在官网买了一个 5C 然后转运回来(新加坡→日本 EMS→国内,沟槽的被税了 51 块,但也比国内代理便宜),又在闲鱼捡了个漏😋,330 块(CNY)买了个全新未拆的 5(也是 5.7.4 最新固件)。

封面图来自 Yubico 和 OpenPGP Org

目录

先决条件

  • YubiKey 具有 5.4 及以上版本固件。
  • 本文主要适用于 Debian 系 Linux(测试于 Ubuntu 26.04,GnuPG 2.4.8),Windows 由于没有设备无法测试,但你可以装 Gpg4win 来试试。
  • 熟悉 Linux 相关命令,知道自己在干什么。
  • 懂得问 AI。

YubiKey OpenPGP 默认密码:

  • User PIN:123456
  • Admin PIN:12345678
  • Reset Code:空(用于重设 PIN,可以不设置)

环境准备

为了安全性,所有操作都可以在全新安装的,启用了硬盘加密的新电脑或虚拟机里进行。如果你使用 VMware Workstation 运行虚拟机,需要在虚拟机 vmx 文件里设置以下参数,来启用完整的 YubiKey 转发:

usb.generic.allowHID = "TRUE"
usb.generic.allowLastHID = "TRUE"
usb.generic.CCID = "TRUE"
usb.generic.allowCCID = "TRUE"
usb.ccid.disable = "TRUE"

如果你以前没在系统里用过智能卡等设备,可能需要先安装一下相关包。安装完后,如果你是隔离的电脑或虚拟机,就可以断网了。

sudo apt update
sudo apt upgrade
sudo apt install gnupg-agent scdaemon pcscd pcsc-tools yubikey-manager

然后在 ~/.gnupg/gpg.conf(没有就创建)里写入以下内容,增加安全性(参考 drduh/YubiKey-Guide):

# 算法偏好
personal-cipher-preferences AES256 AES192 AES
personal-digest-preferences SHA512 SHA384 SHA256
personal-compress-preferences ZLIB BZIP2 ZIP Uncompressed
default-preference-list SHA512 SHA384 SHA256 AES256 AES192 AES ZLIB BZIP2 ZIP Uncompressed
cert-digest-algo SHA512
s2k-digest-algo SHA512
s2k-cipher-algo AES256

# 字符与输出规范
charset utf-8
no-emit-version
keyid-format 0xlong
list-options show-uid-validity
verify-options show-uid-validity

# 安全设置
with-fingerprint
require-cross-certification
require-secmem
no-symkey-cache

# 其它
armor
use-agent
auto-key-locate local,wkd,dane

还需要创建一个文件,并写入内容,来解决 GPG 和智能卡进程的冲突。执行以下命令:

echo "disable-ccid" >> ~/.gnupg/scdaemon.conf

然后执行 gpgconf --kill all 应用配置,再启用下智能卡守护进程:

sudo systemctl enable --now pcscd

之后插拔一下 YubiKey,然后执行以下命令,应该就能看见你的 OpenPGP 智能卡信息了。如果没有的话,尝试重启下电脑?

gpg --card-status
全新的 YubiKey OpenPGP 智能卡信息
全新的智能卡信息

在进行任何操作前(包括更改密码),需要先启用 KDF,这可以避免 PIN 通过明文传输,提高安全性,操作如下:

gpg --edit-card  # 进入智能卡编辑
admin  # 进入管理员模式
kdf-setup  # 设置 KDF,然后需要输入管理员默认密码 12345678
quit  # 退出

生成密钥

在继续进行智能卡设置前,我们先创建一个主密钥。这个主密钥只有 Certify 功能(证明身份、管理子密钥),并且不会存放到 YubiKey,而是放在本地。这个主密钥只会在修改主密钥自身、修改子密钥(例如吊销、轮换子密钥)或者确认他人身份时用到。就像 CA 证书一样,主密钥相当重要,所以需要安全保存好。输入以下命令来开始用专家模式创建密钥:

gpg --expert --full-generate-key

然后会提示你想创建什么样的密钥:

Please select what kind of key you want:
  (1) RSA and RSA
  (2) DSA and Elgamal
  (3) DSA (sign only)
  (4) RSA (sign only)
  (7) DSA (set your own capabilities)
  (8) RSA (set your own capabilities)
  (9) ECC (sign and encrypt) *default*
 (10) ECC (sign only)
 (11) ECC (set your own capabilities)
 (13) Existing key
 (14) Existing key from card
Your selection?

由于 RSA 太长而且慢,我这里准备使用 ECC(椭圆曲线)。输入 11(意为使用 ECC 算法,并且选择该密钥的功能),然后回车(如果你要 RSA,那就输入 8)。

在下一个页面,需要选择密钥的功能:

Possible actions for this ECC key: Sign Certify Authenticate  
Current allowed actions: Sign Certify  

  (S) Toggle the sign capability
  (A) Toggle the authenticate capability
  (Q) Finished

Your selection?

可以看到 GPG 默认为这个密钥加上了 Sign 和 Certify 功能,但我们这个主密钥只需要使用 Certify 就行,因为签名、加解密、验证将会作为三个子密钥,留在 YubiKey 上。所以在这里,输入 s 然后回车,就可以看到默认的 Sign 功能没了,然后输入 q 结束功能设置。

在下一个页面,需要选择主密钥的具体算法:

Please select which elliptic curve you want:
  (1) Curve 25519 *default*
  (2) Curve 448
  (3) NIST P-256
  (4) NIST P-384
  (5) NIST P-521
  (6) Brainpool P-256
  (7) Brainpool P-384
  (8) Brainpool P-512
  (9) secp256k1
Your selection?

我建议这里选择 Curve 448 作为主密钥的算法(输入 2 回车),因其速度快、长度短,但也提供了足够的安全性。另外,YubiKey 是不支持 Curve 448 的(见 支持的椭圆曲线列表),但我觉得这不是问题,因为 Curve 448 只是主密钥的算法,而主密钥不会放到 YubiKey 里(子密钥会使用兼容的曲线)。我测试了一下应该是不会有奇怪的报错的,不过如果你真遇到问题,在这里可以选择 Curve 25519 或 Brainpool 系列曲线。

注意:大部分密钥服务器不支持新的 Curve 448,而只能通过 WKD 或 OPENPGPKEY DNS 记录来分发密钥(教程见 通过 WKD / OPENPGPKEY DNS 记录部署 GPG 公钥)。如果你需要将公钥上传到密钥服务器,请勿使用 Curve 448。

在下一个页面,需要设置主密钥的到期时间:

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)

这个选项其实无所谓,因为主密钥可以自己给自己续期(个人建议主密钥到期后应续期而不是新建一个,除非量子计算机已经完全破解了传统算法)。我这边就设置 20 年,输入 20y 回车,再输入 y 回车来确认到期时间。

接下来要配置姓名和邮箱。对于正式使用,按照 Ubuntu 的文档,姓名最好填写真实姓名,然后是邮箱和注释(注释可以写昵称)。但我建议如果不熟悉 GPG,在这里先填一个测试用的信息,等掌握了所有命令后再正式生成。

GnuPG needs to construct a user ID to identify your key.

Real name: Test User
Email address: [email protected]
Comment: Liups233
You selected this USER-ID:
   "Test User (Liups233) <[email protected]>"

Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit?

加粗部分即为用户 ID。设置好后,输入 o 回车。

然后就需要输入密码保护主密钥。这里建议开个新终端,使用以下命令来生成随机密码,然后粘贴。

tr -dc 'A-Za-z0-9_!@#$%^&*()_+-=' < /dev/random | head -c 24; echo

确定密码后,密钥就生成好了。务必安全地保存好你输入的密码!

gpg: revocation certificate stored as '/home/user/.gnupg/openpgp-revocs.d/6200326380D3BAA0153527C1C1E59009BD9236D7B0E346D59B3BE83DDB5D9AD5.rev'
public and secret key created and signed.

pub   ed448/0x6200326380D3BAA0 2026-06-17 [C] [expires: 2046-06-12]
     Key fingerprint = 62003 26380 D3BAA 01535 27C1C 1E590 09BD9 236D7 B0E34 6D59B
uid                              Test User (Liups233) <[email protected]>

加粗部分是密钥 ID(截取了指纹的前 16 位,如果是非 Curve 448,截取的就是指纹的末 16 位)。

吊销证书

我们还注意到,主密钥生成好后,自动生成了一个吊销证书,存放在 ~/.gnupg/openpgp-revocs.d 下面。我们还需要再生成一个吊销证书,以便在有需要时(例如主密钥泄露或丢失)吊销主密钥及其生成的所有子密钥。

gpg --output revoke.asc --gen-revoke 0x6200326380D3BAA0  # 加粗部分换成你的密钥 ID

然后会提示是否确认,输入 y 回车。接下来要选择吊销原因,选择 1 回车。补充描述不用写,直接回车。最后再次 y 回车。吊销证书现在保存为 revoke.asc 文件,务必保存好。

如果要吊销证书,需要有公钥和吊销证书,不需要私钥也能吊销。首先要从互联网各大密钥服务器获得你的公钥(如果你没发布到网上,那好像也没有吊销的必要)并导入 GPG(使用 gpg --import <公钥文件>),然后再使用 gpg --import revoke.asc 进行吊销,之后再用 gpg -K 你会发现主密钥提示已吊销。最后,你需要再导出吊销后的公钥,将其发布在各大密钥服务器上即可。

YubiKey 智能卡设置

卡密码和用户 ID

首先用 gpg --edit-card 进入智能卡编辑,然后执行 admin 进入管理员模式(大多数命令都需要管理员模式),再执行 passwd 进行智能卡密码设置:

gpg/card> passwd
gpg: OpenPGP card no. XXXXXXXXXXXX detected

1 - change PIN
2 - unblock PIN
3 - change Admin PIN
4 - set the Reset Code
Q - quit

Your selection?

首先输入 1 回车更改用户 PIN 码,会依次提示输入原密码(默认 123456)、新密码、确认新密码。用户 PIN 码至少需要 6 位,可以包含数字、字母、符号。建议不要太简单,也不要太难输。

修改好后,输入 3 回车来更改管理员 PIN 码,也会依次提示输入原密码(默认 12345678)、新密码、确认新密码。管理员 PIN 码至少需要 8 位,建议随机生成(tr -dc 'A-Za-z0-9_!@#$%^&*()_+-=' < /dev/random | head -c 16; echo),然后保存在安全的地方,修改完成后输入 q 回车。

回到智能卡编辑页面,执行 login 设置用户 ID(但我不知道有什么用,只是看到 drduh/YubiKey-Guide 这么做),然后输入管理员 PIN 确认。用户 ID 在刚才 生成密钥 的时候输入过,格式是 姓名 (注释) <邮箱>,如果你忘了,可以在新终端执行 gpg -K 查看。

gpg/card> login
Login data (account name): Test User (Liups233) <[email protected]>

密钥生成选项

再执行 key-attr 可以设置智能卡默认生成的密钥算法,我们这里将签名、加解密、验证的密钥算法都设置为 ECC Curve 25519,依次选择即可,设置过程中需要输入管理员 PIN。

gpg/card> key-attr
Changing card key attribute for: Signature key
Please select what kind of key you want:
  (1) RSA
  (2) ECC
Your selection? 2
Please select which elliptic curve you want:
  (1) Curve 25519 *default*
  (4) NIST P-384
  (6) Brainpool P-256
Your selection? 1
The card will now be re-configured to generate a key of type: ed25519
Note: There is no guarantee that the card supports the requested
     key type or size.  If the key generation does not succeed,
     please check the documentation of your card to see which
     key types and sizes are supported.
Changing card key attribute for: Encryption key
Please select what kind of key you want:
  (1) RSA
  (2) ECC
Your selection? 2
Please select which elliptic curve you want:
  (1) Curve 25519 *default*
  (4) NIST P-384
  (6) Brainpool P-256
Your selection? 1
The card will now be re-configured to generate a key of type: cv25519
Changing card key attribute for: Authentication key
Please select what kind of key you want:
  (1) RSA
  (2) ECC
Your selection? 2
Please select which elliptic curve you want:
  (1) Curve 25519 *default*
  (4) NIST P-384
  (6) Brainpool P-256
Your selection? 1
The card will now be re-configured to generate a key of type: ed25519

安全性增强(可选)

执行 forcesig 命令,然后输入管理员 PIN,可以强制在每次签名时都需要输入用户 PIN,你可以使用 list 命令查看此功能是否开启(加粗部分):

gpg/card> list

Reader ...........: Yubico YubiKey OTP FIDO CCID 00 00
Application ID ...: DXXXXXXXXXXXX
Application type .: OpenPGP
Version ..........: 3.4
Manufacturer .....: Yubico
Serial number ....: 3XXXXXXX
Name of cardholder: [not set]
Language prefs ...: [not set]
Salutation .......:  
URL of public key : [not set]
Login data .......: Test User (Liups233) <[email protected]>
Signature PIN ....: forced
Key attributes ...: ed25519 cv25519 ed25519
Max. PIN lengths .: 127 127 127
PIN retry counter : 3 0 3
Signature counter : 0
KDF setting ......: on
UIF setting ......: Sign=off Decrypt=off Auth=off
Signature key ....: [none]
Encryption key....: [none]
Authentication key: [none]
General key info..: [none]

其它设置(可选)

回到刚才 gpg/card> 的智能卡管理终端,你还可以设置以下内容,具体也可以输入 help 查看:

  • name:持卡人姓名
  • url:公钥获取地址(需要 HTTPS)
  • lang:持卡人惯用语言(ISO 639-1 格式语言代码)

全部修改完成后,执行 quitCTRL + D 退出。

在 YubiKey 上生成子密钥

首先使用 gpg --expert --edit-key <密钥 ID> 进入密钥编辑界面,然后输入 help 命令看下可用的命令。

在可用列表里,有 keytocardaddcardkey 两个命令。我看过很多教程都是在本地生成了子密钥,然后再使用 keytocard 将子密钥移动到智能卡里。但我认为使用 addcardkey 更安全,这个命令可以直接在智能卡内生成子密钥,且子密钥不可能泄露(因为智能卡里的私钥不可导出)。子密钥到期后,可以选择通过本地的主密钥来给子密钥延期,也可以选择吊销旧的子密钥,然后在智能卡内生成新的子密钥(覆盖掉旧的)。

但这种方式有个缺点,如果旧的子密钥被覆盖,或是智能卡丢失了,就无法再用新的加解密子密钥解密以前的加密信息,也无法用新的验证子密钥进行 SSH 登录了(需要更新服务器上的 authorized_keys)。如果你希望将子密钥丢失的的影响降到最低,那么就在本地生成子密钥,然后备份你的密钥(只导出子密钥也行),再使用 keytocard 将子密钥移到智能卡里。或者,更安全的做法是使用另一个 YubiKey,生成新的主密钥和子密钥作为备份密钥(和刚才生成的主密钥不同),然后将备份密钥的加解密子密钥作为主密钥的 ADSK(相当于每次在创建一个加密消息时,会自动添加备份密钥作为新的加密对象)。

所以看你选择什么,我这里就用 addcardkey 了。输入命令后,会提示你要生成哪一种子密钥,依次生成即可。过程中会提示输入智能卡 PIN 码,并且为子密钥指定一个有效期(别超过主密钥有效期就行,有效期可以随时修改),还要输入本地主密钥的密码,相当于给子密钥做一个认证。然后生成密钥的算法刚才我们是用 key-attr 设置为 Curve 25519 的。

注意:三个子密钥生成完后,务必使用 save 命令保存。

在智能卡上生成子密钥
在智能卡上生成子密钥

触摸策略

默认情况下,使用 OpenPGP 协议是不需要触摸 YubiKey 上的金色电容按钮的(通过 gpg --card-status 可以看到 UIF setting 都为 Off)。如果你希望设置在调用子密钥时要求触摸,可以按以下步骤操作:

打开一个新的终端窗口,执行 ykman openpgp keys set-touch -h 看看具体可以设置什么:

YubiKey 设置 OpenPGP 触摸策略
设置 OpenPGP 触摸策略

一共有五个触摸策略,自行阅读红框处,这里我们就将三个子密钥+一个证明密钥(后面会说这是啥)的触摸要求都设置为 On 了,依次执行以下命令(需要输入管理员 PIN 并确认更改):

ykman openpgp keys set-touch SIG ON
ykman openpgp keys set-touch DEC ON
ykman openpgp keys set-touch AUT ON
ykman openpgp keys set-touch ATT ON

证明密钥

在 YubiKey 上生成子密钥后,可以使用出厂内置的 Attestation 证明密钥对生成的密钥进行签名,来证明这个子密钥是在硬件设备上生成的,而不是从外部导入的,即不存在其他副本。详见 OpenPGP Attestation – Yubico。这个功能对于个人可能没用,我纯粹闲的。

使用 ykman openpgp keys attest -h 可以查看命令详情,接下来以签名子密钥为例,讲解如何生成证明证书并验证(命令只在 5.7.4 固件的 YubiKey 上测试过,老版本的命令可能不同,因为 CA 证书变了):

# 生成签名子密钥的证明证书,并输出为 sig.pem 文件(要求输入 PIN 并触摸按钮)
ykman openpgp keys attest SIG sig.pem

# 导出出厂内置的证明证书
ykman openpgp certificates export ATT att.pem

# 下载 Yubico CA 证书和中间证书
curl -o yubico-ca-certs.txt https://developers.yubico.com/PKI/yubico-ca-certs.txt
curl -o yubico-intermediate.pem https://developers.yubico.com/PKI/yubico-intermediate.pem

# 验证证书链,提示 OK 即可
openssl verify -trusted yubico-ca-certs.txt -untrusted yubico-intermediate.pem -untrusted att.pem sig.pem

其它

接下来你就可以把公钥发布到各大公钥服务器了(如果你生成的是测试用的密钥,就重头再来一次),也可以自建一个 WKD,或者放到 DNS 记录里,教程见 通过 WKD / OPENPGPKEY DNS 记录部署 GPG 公钥

至于具体的使用,如 SSH 验证、Git 签名,也许会写新的教程,不过网上资料太多了,动力不足啊,有空再说吧。更多内容可以去 主页 看。