能否用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
相关产品推荐
相关产品推荐

