GPG 签名包含多少信息?

IQA*_*eas 5 pgp digital-signature gnupg

假设您使用 GPG 验证某人的签名:

$ gpg --decrypt statement.txt.sig 
"I am not a crook."
gpg: Signature made 17 Nov 1973 9:31:50 AM CDT using RSA key ID 92861D99
gpg: Good signature from "Richard Nixon <rnixon@whitehouse.gov>"
gpg:                 aka "[jpeg image of size 19022]"
Run Code Online (Sandbox Code Playgroud)

statement.txt.sig文件显然包括签名的声明/数据以及签名人的公钥。但是,输出中包含更多信息,例如全名和电子邮件地址,以及包含在签名者公钥中的 JPEG 图像。

GPG 从哪里获取这些额外数据?它是否包含在文件中statement.txt.sig,还是正在查看您的钥匙圈并“填写”您关于此人的所有额外详细信息?

use*_*686 10

不,信息来自保存在您的公钥环中的证书(或从密钥服务器下载)。签名仅包含查找正确证书所需的一些信息。


使用gpg --list-packetspgpdump

$回声富。> foo.txt
$ gpg --detach-sign foo.txt
$ gpg --list-packets < foo.txt.sig
:签名包:算法1,keyid D24F6CB2C1B52632
    版本 4,创建 1410762670,md5len 0,sigclass 0x00
    摘要算法 10,摘要 25 58 的开始
    散列 subpkt 2 len 4(签名创建于 2014-09-15)
    subpkt 16 len 8(发行者密钥 ID D24F6CB2C1B52632)
    数据:[4091 位]

分离的签名有一个“签名”数据包,其中包含算法、签名时间戳和签名者的 8 字节密钥 ID,用于在您的密钥环中查找签名者的证书。(如果您没有任何带有该 keyid 的公钥,GnuPG 将尝试在公钥服务器中找到一个。)

(我不知道为什么它有两次密钥 ID。)

GnuPG 通过查找 keyid 获取有关签名者的所有信息——用于实际验证签名的公钥,以及用于描述签名者的用户 ID 字段(姓名、地址、照片)。


旁白:请注意,您的示例有一个短的 4 字节 keyid,这非常糟糕,因为已经有数百次已知的短 keyid 冲突,无论是有意的还是意外的。使用keyid-format long你的〜/ .gnupg / gnupg.conf将使其显示较长keyids,尽管这些仍然容易故意碰撞,所以你应该总是导入新的密钥时检查指纹。

(然而,签名包总是在里面保留一个 8 字节的 keyid。有些人配置 GnuPG 将指纹放在自定义字段(符号)中,但不幸的是,软件本身并没有使用它。)


回到签名。如果您gpg --list-packets使用常规(内联)签名,您会看到更多内容:

:compressed packet: algo=1
 :onepass_sig packet: keyid D24F6CB2C1B52632
    版本 3,sigclass 0x00,摘要 10,公钥 1,last=1
:文字数据包:
    模式 b (62), 创建 1410762587, name="",
    原始数据:5 个字节
:签名包:算法1,keyid D24F6CB2C1B52632
    版本 4,创建 1410762587,md5len 0,sigclass 0x00
    摘要算法 10,摘要开始 eb 31
    散列 subpkt 2 len 4(签名创建于 2014-09-15)
    subpkt 16 len 8(发行者密钥 ID D24F6CB2C1B52632)
    数据:[4095 位]

实际签名的消息在“文字数据”数据包中,通常使用 DEFLATE 压缩(pgpdump将显示正在使用的实际算法)。

它前面是一个“onepass_sig”数据包,其唯一目的是提供keyid而不必读取整个消息的结尾——因此GnuPG可以开始搜索keyid并立即继续验证消息。(当从管道中读取时,例如cat|gpg,不可能向前和向后搜索;所有内容都必须一次读取。)


如果需要,您也可以使用签名者的密钥(证书)执行此操作。只需先将其导出到文件:

# gpg --export D24F6CB2C1B52632 | gpg --list-packets
:公钥数据包:
    版本 4,算法 1,创建 1256993643,过期 0
    pkey[0]:[4096 位]
    pkey[1]:[17 位]
    密钥 ID:D24F6CB2C1B52632
:user ID 包: "Mantas Mikul\xc4\x97nas "
:签名包:算法1,keyid D24F6CB2C1B52632
    版本 4,创建 1256993643,md5len 0,sigclass 0x13
    摘要算法 10,摘要 5a e2 的开始
[更多行]

证书也由数据包组成,从一个公钥开始,每个用户 ID(文本标签)带有自签名(以防止有人将假用户 ID 附加到公钥),然后是几个公共子密钥包(再次带有自签名) )。