如何从导出的GPG公钥中获取过期日期?
从ARMOR格式GPG公钥提取过期日期的实用方案
如果已经有导出的armor格式公钥,不用依赖本地密钥环就能提取过期日期,这里有几个靠谱的开源工具和代码实现方案:
1. 用GPG命令行直接解析(无需额外工具)
GPG本身就支持结构化输出和临时密钥环,完全可以直接处理导出的公钥内容,不用永久导入到本地密钥库:
# 替换成你的公钥内容,或者用文件重定向(比如 < public_key.asc) echo "-----BEGIN PGP PUBLIC KEY BLOCK----- [你的公钥内容] -----END PGP PUBLIC KEY BLOCK-----" | gpg --no-default-keyring --keyring /tmp/temp_gpg_keyring.gpg --import > /dev/null && gpg --no-default-keyring --keyring /tmp/temp_gpg_keyring.gpg --list-keys --with-colons heinrichh@duesseldorf.de | grep "^pub:" | cut -d: -f7
细节说明:
--no-default-keyring:避免干扰你本地的默认密钥环,完全隔离操作--keyring /tmp/...:指定临时密钥环文件,用完可以直接删除清理--with-colons:输出结构化的冒号分隔格式,方便精准提取字段- 第7个字段是过期时间:如果返回
0表示永不过期,否则是Unix时间戳,可用date -d @<timestamp>转成可读格式
2. 编程场景:用OpenPGP解析库直接处理
如果需要在代码里集成这个功能,推荐用专门的OpenPGP解析库,不用调用外部gpg命令,更灵活且跨平台:
Python:PGPy库(纯Python实现)
PGPy是轻量的纯Python OpenPGP工具,可以直接解析armor格式密钥:
import pgpy from datetime import datetime # 读取armor公钥文件 with open("your_public_key.asc", "r") as key_file: pubkey_blob = key_file.read() # 解析密钥 pgp_key, _ = pgpy.PGPKey.from_blob(pubkey_blob) # 获取并输出过期时间 expiry_time = pgp_key.expires if expiry_time: print(f"密钥过期时间:{expiry_time.strftime('%Y-%m-%d %H:%M:%S')}") else: print("该密钥永不过期")
安装方式:pip install pgpy
Go:GopenPGP库(ProtonMail维护)
适合Go语言项目的可靠OpenPGP实现:
package main import ( "fmt" "os" "github.com/ProtonMail/gopenpgp/v2/crypto" ) func main() { keyData, err := os.ReadFile("your_public_key.asc") if err != nil { panic(err) } publicKey, err := crypto.NewKeyFromArmored(string(keyData)) if err != nil { panic(err) } expiry := publicKey.GetExpirationTime() if expiry.IsZero() { fmt.Println("密钥永不过期") } else { fmt.Printf("密钥过期时间:%s\n", expiry.Format("2006-01-02 15:04:05")) } }
Java:Bouncy Castle库(Java生态通用)
Bouncy Castle是Java领域常用的加密库,支持完整的OpenPGP解析:
import org.bouncycastle.openpgp.*; import org.bouncycastle.openpgp.operator.jcajce.JcaKeyFingerprintCalculator; import java.io.FileReader; import java.io.IOException; import java.util.Date; public class GPGKeyExpiryChecker { public static void main(String[] args) throws IOException, PGPException { PGPPublicKeyRingCollection keyRingCol = new PGPPublicKeyRingCollection( PGPUtil.getDecoderStream(new FileReader("your_public_key.asc")), new JcaKeyFingerprintCalculator() ); for (PGPPublicKeyRing keyRing : keyRingCol) { for (PGPPublicKey key : keyRing) { if (key.isEncryptionKey()) { long validSeconds = key.getValidSeconds(); if (validSeconds == 0) { System.out.println("密钥永不过期"); } else { Date expiryDate = new Date(key.getCreationTime().getTime() + validSeconds * 1000); System.out.println("密钥过期时间:" + expiryDate); } } } } } }
总结
- 命令行场景:优先用GPG自带的
--with-colons输出方案,简单直接,不用额外安装工具 - 编程场景:选择对应语言的OpenPGP原生解析库,避免依赖系统GPG环境,跨平台更可靠
内容的提问来源于stack exchange,提问作者Grzegorz
相关产品推荐
相关产品推荐

