如何验证gpg签名是否与公钥文件匹配?

时间:2013-09-25 17:06:33

标签: gnupg openpgp

我知道如何使用gpg验证:

$ gpg --verify somefile.sig
gpg: Signature made Tue 23 Jul 2013 13:20:02 BST using RSA key ID E1B768A0
gpg: Good signature from "Richard W.M. Jones <rjones@redhat.com>"
gpg:                 aka "Richard W.M. Jones <rich@annexia.org>"
gpg: WARNING: This key is not certified with a trusted signature!
gpg:          There is no indication that the signature belongs to the owner.
Primary key fingerprint: F777 4FB1 AD07 4A7E 8C87  67EA 9173 8F73 E1B7 68A0

但我真正想做的是根据特定的公钥文件验证文件。

动机是从网站下载大型文件并需要验证它们在使用之前未被篡改的程序的一部分。该网站将包含文件和签名。该程序将附带GPG公钥。当我将文件上传到网站时,我将使用相应的私钥对其进行签名(显然没有分发)。似乎该程序应该能够执行以下操作:

gpg --no-default-keyring --verify file.sig \
    --is-signed-with /usr/share/program/goodkey.asc

但是gpg没有这样的选择。看起来这样做的唯一方法就是解析gpg命令的打印输出,这看起来非常不安全(它包含攻击者控制的文本)。

编辑:我不知道礼仪是什么在这里回答自己的问题,但我找到的答案是使用--status-fd标志。这个标志产生很好的可解析输出,我可以检查所需的指纹:

gpg --status-fd <N> --verify file.sig

在fd N上生成:

[GNUPG:] SIG_ID rpG8ATxU8yZr9SHL+VC/WQbV9ac 2013-07-23 1374582002
[GNUPG:] GOODSIG 91738F73E1B768A0 Richard W.M. Jones <rjones@redhat.com>
[GNUPG:] VALIDSIG F7774FB1AD074A7E8C8767EA91738F73E1B768A0 2013-07-23 1374582002 0 4 0 1 2 00 F7774FB1AD074A7E8C8767EA91738F73E1B768A0
[GNUPG:] TRUST_UNDEFINED

这就是perl的GnuPG库的工作方式。

2 个答案:

答案 0 :(得分:17)

使用特定公钥文件(如密钥环)的唯一方法是文件是GPG(OpenPGP)文件格式而不是ASCII装甲版本(例如pubkey.gpg而不是pubkey.asc)。

所以这将验证文件:

gpg --no-default-keyring --keyring /path/to/pubkey.gpg --verify /path/to/file.txt.gpg

这不会:

gpg --no-default-keyring --keyring /path/to/pubkey.asc --verify /path/to/file.txt.gpg
编辑:关于SuperUser网站上的类似问题,我已经详细介绍了这个问题:

https://superuser.com/questions/639853/gpg-verifying-signatures-without-creating-trust-chain/650359#650359

答案 1 :(得分:10)

我想出了以下脚本:

#!/bin/bash

set -e

keyfile=$(mktemp --suffix=.gpg)
function cleanup {
    rm "$keyfile"
}
trap cleanup EXIT

gpg2 --yes -o "$keyfile" --dearmor "$1"
gpg2 --status-fd 1 --no-default-keyring --keyring "$keyfile" --trust-model always --verify "$2" 2>/dev/null

用作:

$ check-sig.sh <ascii-armored-keyfile> <signature-document>