Как проверить подпись OpenPGP на открытом ключе?

Я работаю над проектом go, который должен будет проверить открытый ключ OpenPGP, чтобы иметь возможность использовать его для проверки подписи файлов.

Я сгенерировал корневой ключ и еще один ключ, который я подписал корневым ключом (назовем второй ключ подписанным). Я экспортировал открытую часть подписанного ключа в защищенный текстовый файл для удобства распространения:

gpg --export -a signed > signed.asc

Я написал этот код, который иллюстрирует то, что я хочу сделать в конце:

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?


person FrontierPsycho    schedule 19.02.2016    source источник
comment
Скорее всего, это не одна подпись. Обычно выдается самоподпись для привязки идентификаторов пользователей и хранения некоторых настроек. Посмотрите на экспортированный ключ, используя gpg --list-packets signed.asc, и вы, вероятно, найдете несколько подписей.   -  person Jens Erat    schedule 19.02.2016
comment
Спасибо за комментарий! Я проверил, что подпись всего одна, и что она правильная. Самоподпись хранится под SelfSignature, а не в срезе Signatures, поэтому я почти уверен, что не ошибаюсь.   -  person FrontierPsycho    schedule 19.02.2016


Ответы (1)


Не уверен, должен ли я закрыть этот вопрос или нет: я нашел ответ. В документах это не очень ясно, но VerifyKeySignature действительно, вероятно, используется только для подразделов. Для проверки подписей открытых ключей других пользователей используйте VerifyUserIdSignature, например:

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