英文:
How to verify an OpenPGP signature on a public key?
问题
我正在处理一个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()
// 读取密钥环
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)
// 读取公共的加密密钥
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)
// signed上只有一个签名,由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
库验证该签名?
英文:
I am working on a go project that will need to verify an OpenPGP public key, to be able to use it to verify file signatures.
I've generated a root key, and another key, which I've signed with the root key (let's call the second key signed). I've exported the public part of the signed key to an armored text file, for easy distribution:
gpg --export -a signed > signed.asc
I've written this go code which illustrates what I want to do, in the end:
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)
}
}
When I run it, I give keyring
my public keyring (~/.gnupg/pubring.gpg
) and signedkey
my exported signed key (signed.asc
).
In production, the idea is to also export the root public key from pubring.gpg
into armored text, and embed that in the code.
The signature fails to verify with the following error:
panic: openpgp: invalid signature: hash tag doesn't match
Looking at the code of VerifyKeySignature
(and especially this comment), I get the feeling that it's meant to only be used to verify signatures on subkeys, rather than other keys.
So, the question is, given two public PGP keys, one signed by the other, how do I verify that signature using the openpgp
library?
答案1
得分: 1
我不确定是否应该关闭这个问题:我找到了答案。在文档中并不是很清楚,但是VerifyKeySignature
可能只用于子密钥。要验证其他用户公钥上的签名,请使用VerifyUserIdSignature
,像这样:
err = rootidentity.PrimaryKey.VerifyUserIdSignature("signed", signed.PrimaryKey, signature)
if err != nil {
panic(err)
}
英文:
Not sure whether I should close this question or not: I found the answer. It isn't very clear in the docs, but VerifyKeySignature
is indeed probably only used for subkeys. For verifying the signatures on other users' public keys, use VerifyUserIdSignature
, like so:
err = rootidentity.PrimaryKey.VerifyUserIdSignature("signed", signed.PrimaryKey, signature)
if err != nil {
panic(err)
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论