如何从密钥S表达式与创建时间重建OpenPGP智能卡公钥?
从OpenPGP智能卡重建公钥的可行性及实现方法
可行性确认
完全可行。OpenPGP智能卡存储了公钥的核心密钥材料(如RSA的模数n、公钥指数e,或椭圆曲线的公钥点)、算法标识,以及密钥创建时间(KEY-TIME),这些信息足以重建完整的OpenPGP公钥并生成自签名。
使用GPG工具链的实现步骤
提取智能卡中的公钥S表达式与创建时间
执行指定的gpg-connect-agent命令,生成包含公钥数据的out文件:gpg-connect-agent > /datafile out > scd readkey OPENPGP.1 OK > /bye打开
out文件,记录KEY-TIME后的时间戳(如1633046400),同时保留公钥的S表达式内容。将S表达式转换为OpenPGP公钥格式
使用libgcrypt的命令行工具gcrypt-tool,将S表达式转换为GPG可识别的公钥文件:gcrypt-tool --export --openpgp --s-expression out > raw-pubkey.gpg补全公钥元数据并生成自签名
- 先查看智能卡上的用户信息(姓名、邮箱):
gpg --card-status - 导入原始公钥,添加用户ID并生成自签名:
gpg --import raw-pubkey.gpg # 替换为卡上的用户ID,如 "John Doe <john@example.com>" gpg --edit-key [公钥指纹] gpg> adduid # 输入用户信息后确认 gpg> save - 若需要强制匹配KEY-TIME的创建时间,可使用
--faked-system-time参数:gpg --faked-system-time 1633046400 --edit-key [公钥指纹] gpg> adduid gpg> save
- 先查看智能卡上的用户信息(姓名、邮箱):
使用libgcrypt函数的编程实现
如果需要通过代码实现,可调用libgcrypt的以下核心函数:
- 解析S表达式:
gcry_sexp_new(),从out文件读取公钥的S表达式字符串,生成libgcrypt的S表达式对象。 - 提取公钥参数:
gcry_pk_get_key(),从S表达式中提取公钥算法类型、密钥材料(如RSA的n和e)。 - 创建OpenPGP公钥结构:
gcry_openpgp_pubkey_new(),初始化空的OpenPGP公钥对象,设置算法标识和密钥材料。 - 设置创建时间:
gcry_openpgp_pubkey_set_creation_time(),传入从KEY-TIME获取的时间戳。 - 添加用户ID:
gcry_openpgp_pubkey_add_userid(),传入智能卡上的用户ID字符串。 - 生成自签名:
gcry_openpgp_sign(),结合智能卡驱动调用私钥完成公钥与用户ID的自签名。 - 导出公钥:
gcry_openpgp_export(),将重建后的OpenPGP公钥导出为文件或字节流。
内容的提问来源于stack exchange,提问作者kinetic_constellation
相关产品推荐
相关产品推荐

