我知道如何使用 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 <[email protected]>"
gpg: aka "Richard W.M. Jones <[email protected]>"
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 <[email protected]>
[GNUPG:] VALIDSIG F7774FB1AD074A7E8C8767EA91738F73E1B768A0 2013-07-23 1374582002 0 4 0 1 2 00 F7774FB1AD074A7E8C8767EA91738F73E1B768A0
[GNUPG:] TRUST_UNDEFINED
这就是 Perl 的 GnuPG 库的工作原理。
使用特定公钥文件(如密钥环)的唯一方法是该文件采用 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
编辑:对于超级用户网站上的类似问题,我对此进行了更详细的介绍:
我想出了以下脚本:
#!/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>
如果您已在 /usr/share/program/goodkey.asc 准备好密钥
先导入
gpg --import /usr/share/program/goodkey.asc
然后执行验证命令
gpg --verify somefile.sig somefile