简体   繁体   中英

How to verify an OpenPGP signature on a public key?

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?

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)
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM