You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

能否用Golang OpenPGP包从Armored密钥读取实体身份信息?

如何用Golang OpenPGP包从Armored密钥中读取身份信息?

当然可以实现!你遇到的entity.Identities只返回空键的问题,是因为你用的go-pgp库的GetEntity方法在解析密钥时,没有正确提取身份字段。咱们来一步步解决这个问题:

问题原因

你通过pgp.GenerateKeyPair生成的密钥本身是包含test (tst comment) <test@email.com>这个身份信息的,但pgp.GetEntity方法在解析Armored密钥时,没有正确解析出用户ID字段,导致返回的实体身份信息为空。

解决方案:改用官方库解析密钥

我们可以直接使用Golang官方的golang.org/x/crypto/openpgp和armor包来解析Armored密钥,这样就能正确提取出完整的身份信息。修改后的测试代码如下:

package main

import (
	"bytes"
	"log"
	"testing"

	"github.com/jchavannes/go-pgp/pgp"
	"golang.org/x/crypto/openpgp"
	"golang.org/x/crypto/openpgp/armor"
)

func TestID(t *testing.T) {
	keypair, err := pgp.GenerateKeyPair("test", "tst comment", "test@email.com")
	if err != nil {
		t.Fatalf("failed to generate keypair: %s", err)
	}

	// 解码Armored公钥
	block, err := armor.Decode(bytes.NewReader([]byte(keypair.PublicKey)))
	if err != nil {
		t.Fatalf("failed to decode public key armor: %s", err)
	}

	// 读取密钥环并获取实体
	entities, err := openpgp.ReadKeyRing(block.Body)
	if err != nil {
		t.Fatalf("failed to read public key ring: %s", err)
	}

	// 遍历输出所有身份信息
	for _, entity := range entities {
		for identityStr, identity := range entity.Identities {
			log.Printf("完整身份字符串: %s", identityStr)
			log.Printf("姓名: %s", identity.UserId.Name)
			log.Printf("备注: %s", identity.UserId.Comment)
			log.Printf("邮箱: %s", identity.UserId.Email)
		}
	}
}

运行这段代码后,你就能看到预期的输出:

202X/XX/XX XX:XX:XX 完整身份字符串: test (tst comment) <test@email.com>
202X/XX/XX XX:XX:XX 姓名: test
202X/XX/XX XX:XX:XX 备注: tst comment
202X/XX/XX XX:XX:XX 邮箱: test@email.com

额外方案:完全使用官方库生成并读取密钥

如果你不需要依赖第三方的go-pgp库,也可以直接用官方库生成密钥并读取身份信息,这样更直接:

package main

import (
	"bytes"
	"log"
	"testing"
	"time"

	"golang.org/x/crypto/openpgp"
	"golang.org/x/crypto/openpgp/armor"
	"golang.org/x/crypto/openpgp/packet"
)

func TestOfficialOpenPGP(t *testing.T) {
	// 配置密钥生成参数
	config := &packet.Config{
		DefaultHash: packet.HashSHA256,
		Time:        func() time.Time { return time.Now() },
	}

	// 创建包含身份信息的实体
	entity, err := openpgp.NewEntity("test", "tst comment", "test@email.com", config)
	if err != nil {
		t.Fatalf("failed to create entity: %s", err)
	}

	// 生成Armored公钥(可选,如果你需要导出密钥)
	var pubKeyBuf bytes.Buffer
	w, err := armor.Encode(&pubKeyBuf, openpgp.PublicKeyType, nil)
	if err != nil {
		t.Fatalf("failed to encode public key: %s", err)
	}
	if err := entity.Serialize(w); err != nil {
		t.Fatalf("failed to serialize entity: %s", err)
	}
	w.Close()
	log.Println("Armored公钥:\n", pubKeyBuf.String())

	// 直接读取实体的身份信息
	for identityStr, identity := range entity.Identities {
		log.Printf("完整身份字符串: %s", identityStr)
		log.Printf("姓名: %s", identity.UserId.Name)
		log.Printf("备注: %s", identity.UserId.Comment)
		log.Printf("邮箱: %s", identity.UserId.Email)
	}
}

这段代码生成密钥后,不需要额外解析Armored字符串,就能直接访问entity.Identities获取所有身份详情。

内容的提问来源于stack exchange,提问作者user4466350

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 09:03:13