Bash

在 BASH 腳本中驗證 PGP 簽名的正確方法(固定精確的長指紋)

  • August 29, 2020

我有:

  1. 一份文件
  2. 該文件的 ASCII 裝甲格式的分離 PGP 簽名和
  3. 一個 40 個字元(長格式)的指紋,用於辨識一個必須具有有效簽名的密鑰

gpg使用*nix 上的命令編寫 BASH 腳本以驗證給定簽名對於給定文件是否有效(僅適用於給定指紋)的正確方法是什麼?

注意:理想情況下,該解決方案不會僅從 – 解析 STDOUT,gpg這樣如果將來輸出的單詞或格式稍有變化,所提供解決方案中的 BASH 腳本就不會中斷。

而且,特別重要的是,分離的簽名可以由多個密鑰簽名。因此,如果攻擊者獲取文件及其分離的簽名並編輯文件,同時將自己的簽名添加到分離的簽名中,則此解決方案應該會失敗。請注意,在這種攻擊中,我們將其指紋固定在腳本中的密鑰會出現 BAD 簽名,而攻擊者的密鑰會出現 GOOD 簽名,這是無關緊要的。在這種情況下,解決方案必須失敗。

例如,考慮以下情況:

  1. https://files.pythonhosted.org/packages/cb/85/8a1588a04172e0853352ecfe214264c65a62ab35374d9ad9c569cf94c2a3/python_gnupg-0.4.6-py2.py3-none-any.whl
  2. https://files.pythonhosted.org/packages/cb/85/8a1588a04172e0853352ecfe214264c65a62ab35374d9ad9c569cf94c2a3/python_gnupg-0.4.6-py2.py3-none-any.whl.asc
  3. CA749061914EAC138E66EADB9147B477339A9B86

目前我的 BASH 腳本中有以下內容

#!/bin/bash

ONLY_TRUST_THIS_FINGERPRINT='CA749061914EAC138E66EADB9147B477339A9B86'

tmpDir="`mktemp -d`" || exit 1
pushd "${tmpDir}"

wget https://files.pythonhosted.org/packages/cb/85/8a1588a04172e0853352ecfe214264c65a62ab35374d9ad9c569cf94c2a3/python_gnupg-0.4.6-py2.py3-none-any.whl
wget https://files.pythonhosted.org/packages/cb/85/8a1588a04172e0853352ecfe214264c65a62ab35374d9ad9c569cf94c2a3/python_gnupg-0.4.6-py2.py3-none-any.whl.asc
wget https://keys.openpgp.org/vks/v1/by-fingerprint/CA749061914EAC138E66EADB9147B477339A9B86

mkdir gnupg
gpg --homedir "${tmpDir}/gnupg" --import CA749061914EAC138E66EADB9147B477339A9B86

上面的腳本中應該遵循什麼命令來安全地確認文件具有來自與我們固定指紋匹配的私鑰的有效簽名?

編輯:這是一個簡單的範例輸出,gpg --verify ...它具有攻擊者的 GOOD 簽名和實際開發人員的 BAD 簽名;它應該失敗。

user@disp2952:/tmp/tmp.nUmxfwbwfK$ gpg --homedir gnupg/ --verify python_gnupg-0.4.6-py2.py3-none-any.whl.asc
gpg: WARNING: unsafe permissions on homedir '/tmp/tmp.nUmxfwbwfK/gnupg'
gpg: assuming signed data in 'python_gnupg-0.4.6-py2.py3-none-any.whl'
gpg: Signature made Sat 29 Aug 2020 10:04:03 PM +0545
gpg:                using RSA key 2DA3BAD0DB41087CA7E5E4C1F93C17B957F73F5A
gpg: Good signature from "Mallory <mallory@mail.ru>" [unknown]
gpg: Signature made Fri 17 Apr 2020 07:54:23 PM +0545
gpg:                using RSA key 9147B477339A9B86
gpg: BAD signature from "Vinay Sajip (CODE SIGNING KEY) <vinay_sajip@yahoo.co.uk>" [unknown]
user@disp2952:/tmp/tmp.nUmxfwbwfK$ echo $?
1
user@disp2952:/tmp/tmp.nUmxfwbwfK$ 

使用gpgv

gpgv --homedir "${tmpDir}/gnupg" --keyring "${tmpDir}/gnupg/pubring.kbx" python_gnupg-0.4.6-py2.py3-none-any.whl.asc python_gnupg-0.4.6-py2.py3-none-any.whl

如果使用給定密鑰環中的密鑰驗證所有簽名,它將僅指示成功(退出程式碼 0)。

如果您想檢查您導入的密鑰是否與您要求的指紋匹配,您可以要求gpg列出密鑰環中與指紋匹配的密鑰:

gpg --homedir "${tmpDir}/gnupg" --no-default-keyring --keyring "${tmpDir}/gnupg/pubring.kbx" --list-keys "${ONLY_TRUST_THIS_FINGERPRINT}"

如果密鑰存在於密鑰環中,則表示成功,否則失敗。

如果你想提高信任檢查,你應該真正儲存下載的密鑰,並且始終使用儲存的密鑰來驗證下載,而不是每次都重新下載密鑰。這是在某些發行版(特別是 Debian)中用於驗證新上游版本的方法:已知良好密鑰儲存在包源中(在 Debian 中,而不是上游),並且只有在新版本由已知良好的密鑰。

引用自:https://unix.stackexchange.com/questions/606960