如何验证来自 Facebook 的电子邮件签名?

mar*_*oju 5 encryption digital-signature

Facebook 允许用户

将 OpenPGP 公钥添加到他们的个人资料中;这些密钥可用于“端到端”加密从 Facebook 发送到您首选电子邮件帐户的通知电子邮件。–保护来自 Facebook 的电子邮件通信

Facebook 在https://www.facebook.com/facebook/publickey/download/提供了一个公钥 (0x2F3898CEDEE958CF)

关于我的帐户的“加密通知”已通过 Facebook (noreply@facebookmail.com) 的电子邮件反复发送给我。这些电子邮件使用我上传到 Facebook 的公钥加密。这些电子邮件的签名密钥 (0x3028CF59770E7A01) 不是 Facebook 提供的密钥 (0x2F3898CEDEE958CF)。当我尝试使用 Enigmail 导入密钥 0x3028CF59770E7A01 时,会显示以下通知:

ID 为 0x3028CF59770E7A01 的密钥在密钥服务器上不可用。最有可能的是,密钥的所有者没有将他们的密钥上传到密钥服务器。

请要求消息的发件人通过电子邮件向您发送他们的密钥。

  • 我找不到联系邮件发件人的方法。
  • 我没有找到密钥 0x3028CF59770E7A01 的来源。

我的主要问题:如何验证来自 Facebook 的电子邮件签名?

顺便说一句:为什么 Facebook 会使用产生无法验证的签名的密钥?

更新

在密钥服务器上查找密钥 0x2F3898CEDEE958CF(参见例如keyserver.ubuntu.com)将显示最近包含的子密钥 0x3028CF59770E7A01

sub rsa4096/3028cf59770e7a01 2019-07-08T16:09:07Z            
sig sbind 2f3898cedee958cf 2019-07-08T16:09:07Z ____________________ 2020-01-04T20:00:00Z []
Run Code Online (Sandbox Code Playgroud)

这与 Facebook 在其帖子保护来自 Facebook 的电子邮件通信中提供的信息一致

Facebook 的 OpenPGP 密钥包含一个长期主密钥和短期子密钥;这使我们能够经常轮换我们的操作密钥,同时随着时间的推移保持信任网络和一致的身份。

然而,这个子密钥显然不是公开的,并且尝试从密钥服务器接收这个丢失的密钥失败。

gpg: Signature made Di 06 Aug 2019 17:56:19 CEST
gpg:                using RSA key 3B6C6808FC9D75EDAE0184E73028CF59770E7A01
gpg: Can't check signature: No public key
Run Code Online (Sandbox Code Playgroud)

mar*_*oju 4

Facebook提供的facebook.asc实际上持有两个子,执行可以看到gpg --show-key --with-colons facebook.asc

pub:-:4096:1:2F3898CEDEE958CF:1431903600:1581038771::-:
uid:::::::::Facebook, Inc.:
sig:::1:2F3898CEDEE958CF:1517966771:::::[selfsig]::13x:
sub:-:4096:1:D2CC929B77D6D6F9:1547468530:1564686000:::
sig:::1:2F3898CEDEE958CF:1547468530:::::[keybind]::18x:
sub:-:4096:1:3028CF59770E7A01:1562602147:1578168000:::
sig:::1:2F3898CEDEE958CF:1562602147:::::[keybind]::18x:
Run Code Online (Sandbox Code Playgroud)

请注意,第二个子项是不祥的 0x3028CF59770E7A01。

将此文件导入到我的密钥环 ( gpg --import facebook.asc ) 中,突然就可以了

gpg: Signature made Di 06 Aug 2019 18:00:09 CEST
gpg:                using RSA key 3B6C6808FC9D75EDAE0184E73028CF59770E7A01
gpg: Good signature from "Facebook, Inc." [unknown]
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: 31A7 0953 D8D5 90BA 1FAB  3776 2F38 98CE DEE9 58CF
     Subkey fingerprint: 3B6C 6808 FC9D 75ED AE01  84E7 3028 CF59 770E 7A01
Run Code Online (Sandbox Code Playgroud)

虽然 Enigmail 的密钥管理多次无法下载子密钥 0x3028CF59770E7A01(例如从 hkps://keys.openpgp.org 或 hkps://hkps.pool.sks-keyservers.net),但可以通过以下方式接收子密钥gpg --keyserver hkps://keyserver.ubuntu.com --recv-keys 0x3028CF59770E7A01

gpg: key 2F3898CEDEE958CF: 586 duplicate signatures removed
gpg: key 2F3898CEDEE958CF: 1417 signatures not checked due to missing keys
gpg: key 2F3898CEDEE958CF: 1 signature reordered
gpg: key 2F3898CEDEE958CF: public key "Facebook, Inc." imported
gpg: marginals needed: 3  completes needed: 1  trust model: pgp
gpg: depth: 0  valid:   2  signed:   0  trust: 0-, 0q, 0n, 0m, 0f, 2u
gpg: next trustdb check due at 2021-02-07
gpg: Total number processed: 1
gpg:               imported: 1
Run Code Online (Sandbox Code Playgroud)

更新我的默认密钥服务器从密钥中剥离用户 ID,导致new key but contains no user ID - skipped. 使用 keyserver.ubuntu.com 可以解决这个问题。这个答案解释了原因