Go 如何验证公钥上的OpenPGP签名?

Go 如何验证公钥上的OpenPGP签名?,go,openpgp,Go,Openpgp,我正在从事一个go项目,该项目需要验证OpenPGP公钥,以便能够使用它来验证文件签名 我已经生成了一个根密钥和另一个密钥,我用根密钥对其进行了签名(我们称之为第二个已签名密钥)。我已将签名密钥的公共部分导出到一个装甲文本文件中,以便于分发: gpg --export -a signed > signed.asc 我已经编写了这段go代码,说明了我想做什么,最后: package main import ( "flag" "fmt" "golang.org/x/

我正在从事一个go项目,该项目需要验证OpenPGP公钥,以便能够使用它来验证文件签名

我已经生成了一个根密钥和另一个密钥,我用根密钥对其进行了签名(我们称之为第二个已签名密钥)。我已将签名密钥的公共部分导出到一个装甲文本文件中,以便于分发:

gpg --export -a signed > signed.asc
我已经编写了这段go代码,说明了我想做什么,最后:

package main

import (
    "flag"
    "fmt"
    "golang.org/x/crypto/openpgp"
    "os"
)

func main() {
    var keyringpath string
    var signedkeypath string
    flag.StringVar(&keyringpath, "keyring", "", "keyring")
    flag.StringVar(&signedkeypath, "signedkey", "", "signed key")
    flag.Parse()

    // read the keyring
    keyring, err := os.Open(keyringpath)
    if err != nil {
            panic(err)
    }

    el, err := openpgp.ReadKeyRing(keyring)
    if err != nil {
            panic(err)
    }

    var rootidentity *openpgp.Entity
    for _, entity := range el {
            if _, ok := entity.Identities["root"]; ok {
                    rootidentity = entity
            }
    }

    fmt.Printf("%+v\n", rootidentity)

    // read the public armored key
    signedkey, err := os.Open(signedkeypath)
    if err != nil {
            panic(err)
    }

    el, err = openpgp.ReadArmoredKeyRing(signedkey)
    if err != nil {
            panic(err)
    }

    signed := el[0]

    fmt.Printf("%+v\n", signed)

    // there is only one signature on signed, the one produced by root
    signature := signed.Identities["signed"].Signatures[0]

    err = rootidentity.PrimaryKey.VerifyKeySignature(signed.PrimaryKey, signature)
    if err != nil {
            panic(err)
    }
}
当我运行它时,我给出了
keyring
我的公钥环(
~/.gnupg/pubring.gpg
)和
signedkey
我导出的签名密钥(
signed.asc

在生产中,我们的想法是将根公钥从
pubring.gpg
导出到铠装文本中,并将其嵌入到代码中

签名无法验证,出现以下错误:

panic: openpgp: invalid signature: hash tag doesn't match
查看
VerifyKeySignature
(尤其是)的代码,我感觉它只用于验证子键上的签名,而不是其他键上的签名


因此,问题是,给定两个公共PGP密钥,一个由另一个签名,如何使用
openpgp
库验证该签名?

不确定是否应关闭此问题:我找到了答案。文档中不太清楚,但是
VerifyKeySignature
实际上可能只用于子键。要验证其他用户公钥上的签名,请使用
VerifyUserIdSignature
,如下所示:

err = rootidentity.PrimaryKey.VerifyUserIdSignature("signed", signed.PrimaryKey, signature)
if err != nil {
        panic(err)
}

我不确定是否应该结束这个问题:我找到了答案。文档中不太清楚,但是
VerifyKeySignature
实际上可能只用于子键。要验证其他用户公钥上的签名,请使用
VerifyUserIdSignature
,如下所示:

err = rootidentity.PrimaryKey.VerifyUserIdSignature("signed", signed.PrimaryKey, signature)
if err != nil {
        panic(err)
}

很可能不止一个签名。通常,会发布一个自签名来绑定用户ID,并存储一些设置。使用
gpg--list packets signed.asc查看导出的密钥,您可能会发现多个签名。感谢您的评论!我检查了一下只有一个签名,而且是正确的。自签名存储在
SelfSignature
下,而不是
Signatures
切片中,因此我很确定我也没有错误地使用它。很可能不仅仅是一个签名。通常,会发布一个自签名来绑定用户ID,并存储一些设置。使用
gpg--list packets signed.asc查看导出的密钥,您可能会发现多个签名。感谢您的评论!我检查了一下只有一个签名,而且是正确的。自签名存储在
SelfSignature
下,而不是
Signatures
切片中,因此我很确定我也没有错误地使用它。