如何自动信任GPG公钥?

47
我试图在我们设备的安装过程中添加我的GPG公钥。其目的是在管理员使用管理门户将重要文件(例如日志)拉入本地之前加密它们,然后使用私钥解密。 计划是将公钥导出到一个文件中,并使设备安装过程使用gpg --import命令导入它。但我意识到,在进行任何加密之前,需要信任/签署该密钥。 如何在安装时使该密钥得到信任,而无需任何人工干预? 顺便说一下,我们设备的操作系统是Ubuntu虚拟机,我们使用Kickstart自动化。
16个回答

38

你的问题实际上是“如何使用加密方式而不让gpg因密钥不受信任而犹豫不决?”

一个答案是您可以对密钥进行签名。

gpg --edit-key YOUR_RECIPIENT
sign
yes
save

另一种方法是让gpg继续信任。

gpg --encrypt --recipient YOUR_RECIPIENT --trust-model always YOUR_FILE

3
这两种解决方案都不适合批量使用。更好的方法是以下面楼层提到的方式(https://dev59.com/zGcs5IYBdhLWcg3wHwXU#13131115),即使用“--import-ownertrust”命令将密钥标记为受信任的。 - Wejn
由于某些原因,在Gpg4Win上使用“trust”似乎无法用于签名或信任密钥。我不得不使用“sign”。 - FilBot3
2
“trust-model always” 设置无效 - gpg 仍会打印未受信任密钥的警告。 - mymedia

23

恰好我有一个与 OP 相似的情况 - 我正在尝试使用公钥/私钥来为不同的嵌入式设备签名和加密固件。由于目前还没有回答显示如何向已导入的密钥添加信任,因此这是我的答案。

在测试机上创建和测试密钥后,我将其导出为 ascii 格式:

$ gpg --export -a <hex_key_id> > public_key.asc
$ gpg --export-secret-keys -a <hex_key_id> > private_key.asc

然后将它们进行了安全复制并导入到构建服务器:

$ gpg --import public_key.asc
$ gpg --import private_key.asc

重要提示:添加信任

现在编辑密钥以添加最终信任:

$ gpg --edit-key <user@here.com>

gpg>提示符下,输入trust,然后输入5表示绝对信任,接着输入y确认,最后输入quit

现在使用测试文件进行测试:

$ gpg --sign --encrypt --yes --batch --status-fd 1 --recipient "recipient" --output testfile.gpg testfile.txt

报道的内容

...
[GNUPG:] END_ENCRYPTION

没有添加信任,我会得到各种错误(不限于以下内容):

gpg: There is no assurance this key belongs to the named user
gpg: testfile.bin: sign+encrypt failed: Unusable public key

这将把信任级别设置为未知。 - Oliver

15

使用--trust-model选项是告诉GPG信任它的所有密钥的更简单的方法:

    gpg -a --encrypt -r <recipient key name> --trust-model always

从 man 页面中得知:

  --trust-model pgp|classic|direct|always|auto

    Set what trust model GnuPG should follow. The models are:

      always Skip  key  validation  and assume that used 
             keys are always fully trusted. You generally 
             won't use this unless you are using some 
             external validation scheme. This option also 
             suppresses the "[uncertain]" tag printed 
             with signature checks when there is no evidence 
             that the user ID is bound to the key.  Note that 
             this trust model still does  not  allow  the use 
             of expired, revoked, or disabled keys.

1
我喜欢这种明确信任密钥仅用于此次加密调用的方式,而不是全局性地信任。 - John McGehee

11
将密钥ID替换为trusted-key 0x0123456789ABCDEF后添加到~/.gnupg/gpg.conf中。这相当于最终信任此密钥,这意味着由其完成的认证将被视为有效。仅将此密钥标记为有效而不信任它更加困难,需要签名或切换信任模型为direct。如果您确定只导入有效密钥,则可以通过添加trust-model always将所有密钥都标记为有效。在后一种情况下,请确保禁用自动密钥检索(默认情况下未启用)。

11

以下内容对我有帮助:

尝试加密文件时会出现以下响应:

gpg -e --yes -r <uid> <filename>

It is NOT certain that the key belongs to the person named
in the user ID.  If you *really* know what you are doing,
you may answer the next question with yes.

Use this key anyway? (y/N)

That causes my shell script to fail.

我:

$gpg --edit-key <uid>

gpg> trust

Please decide how far you trust this user to correctly verify other 
users' keys (by looking at passports, checking fingerprints from 
different sources, etc.)

  1 = I don't know or won't say
  2 = I do NOT trust
  3 = I trust marginally
  4 = I trust fully
  5 = I trust ultimately
  m = back to the main menu

Your decision? 5
Do you really want to set this key to ultimate trust? (y/N) y

Please note that the shown key validity is not necessarily correct
unless you restart the program.

gpg> quit

现在加密功能正常运行。

6
这怎么解决了OP的问题:“在安装时没有任何人工干预”? - peetasan
2
--command-fd 或:echo -e "trust\n5\ny" > x.cmd gpg2 --command-file x.cmd –edit-key AA11BB22 - rhoerbe

8
基于 @tersmitten 的文章和一些试错,我最终得到了以下命令行,可以在没有用户交互的情况下信任给定密钥环中的所有密钥。 我将其用于与 StackEschange Blackboxhiera-eyaml-gpg 一起使用的密钥:
# The "-E" makes this work with both GNU sed and OS X sed
gpg --list-keys --fingerprint --with-colons |
  sed -E -n -e 's/^fpr:::::::::([0-9A-F]+):$/\1:6:/p' |
  gpg --import-ownertrust

个人而言,我更喜欢一种将结果存储在trustdb文件本身中的解决方案,而不是依赖于共享Git存储库外部的用户环境。


2
能否请下投票反对这个回答的人解释一下为什么这样做? - Capt. Crunch
这段代码可以使用"gpg --export-ownertrust"进行简化。 - rhoerbe
2
简化版:gpg --export-ownertrust | sed 's/:.*/:5:/' | gpg --import-ownertrust翻译: - dessert

4

这里有一个我发现的用于自动化GnuPG密钥管理的技巧,提示是heredoc + --command-fd 0就像魔法一样。以下是一个简化版本的脚本,旨在帮助自动化GnuPG。

#!/usr/bin/env bash
## First argument should be a file path or key id
Var_gnupg_import_key="${1}"
## Second argument should be an integer
Var_gnupg_import_key_trust="${2:-1}"
## Point to preferred default key server
Var_gnupg_key_server="${3:-hkp://keys.gnupg.net}"
Func_import_gnupg_key_edit_trust(){
    _gnupg_import_key="${1:-${Var_gnupg_import_key}}"
    gpg --no-tty --command-fd 0 --edit-key ${_gnupg_import_key} <<EOF
trust
${Var_gnupg_import_key_trust}
quit
EOF
}
Func_import_gnupg_key(){
    _gnupg_import_key="${1:-${Var_gnupg_import_key}}"
    if [ -f "${_gnupg_import_key}" ]; then
        echo "# ${0##*/} reports: importing key file [${_gnupg_import_key}]"
        gpg --no-tty --command-fd 0 --import ${_gnupg_import_key} <<EOF
trust
${Var_gnupg_import_key_trust}
quit
EOF
    else
        _grep_string='not found on keyserver'
        gpg --dry-run --batch --search-keys ${_gnupg_import_key} --keyserver ${Var_gnupg_key_server} | grep -qE "${_grep_string}"
        _exit_status=$?
        if [ "${_exit_status}" != "0" ]; then
            _key_fingerprint="$(gpg --no-tty --batch --dry-run --search-keys ${_gnupg_import_key} | awk '/key /{print $5}' | tail -n1)"
            _key_fingerprint="${_key_fingerprint//,/}"
            if [ "${#_key_fingerprint}" != "0" ]; then
                echo "# ${0##*/} reports: importing key [${_key_fingerprint}] from keyserver [${Var_gnupg_key_server}]"
                gpg --keyserver ${Var_gnupg_key_server} --recv-keys ${_key_fingerprint}
                Func_import_gnupg_key_edit_trust "${_gnupg_import_key}"
            else
                echo "# ${0##*/} reports: error no public key [${_gnupg_import_key}] as file or on key server [${Var_gnupg_key_server}]"
            fi
        else
            echo "# ${0##*/} reports: error no public key [${_gnupg_import_key}] as file or on key server [${Var_gnupg_key_server}]"
        fi
    fi
}
if [ "${#Var_gnupg_import_key}" != "0" ]; then
    Func_import_gnupg_key "${Var_gnupg_import_key}"
else
    echo "# ${0##*/} needs a key to import."
    exit 1
fi

运行 script_name.sh 'path/to/key' '1'script_name.sh 'key-id' '1' 导入一个密钥并分配一个信任值为 1,或使用 script_name.sh 'path/to/key' '1' 'hkp://preferred.key.server' 编辑所有值。

现在加密应该没有问题了,但即使有问题,以下选项 --always-trust 也应允许加密。

gpg --no-tty --batch --always-trust -e some_file -r some_recipient -o some_file.gpg

如果您想看到这个过程,则可以查看Travis-CI构建日志以及如何使用助手脚本GnuPG_Gen_Key.sh来生成和导入密钥。第二版的助手脚本将更加简洁易修改,但它是一个很好的起点。

4

这个一行代码会从标准输入中提取指纹,将其格式化为--import-ownertrust标志所需的格式,并使用所有者信任值更新信任数据库。

根据gpg手册的详细说明,如果信任数据库严重损坏并且/或者您有最近的所有者信任备份,则应使用此标志重新创建信任数据库。

gpg --list-keys --fingerprint \
    | grep ^pub -A 1 \
    | tail -1 \
    | tr -d ' ' \
    | awk 'BEGIN { FS = "\n" } ; { print $1":6:" }' \
    | gpg --import-ownertrust

3
因为没有解释这段代码是做什么或原因,所以被踩了。 - Profpatsch
我添加了一些信息以便更好的清晰度,因为这个一行代码对我很有帮助 :-) - silveiralexf

3

Unix based:

echo -e "5\ny\n" |  gpg --homedir . --command-fd 0 --expert --edit-key user@exaple.com trust;

如需更多信息,请阅读此帖子。如果您正在创建多个密钥,它会详细介绍。


1
太糟糕了,你不应该使用交互式菜单流来自动化这些东西。 - Profpatsch
请在您的答案中添加一些解释,以便其他人可以从中学习 - echo 命令是做什么用的? - Nico Haase

3

信任导入的 GPG 密钥的一种方法:

gpg --import <user-id.keyfile>
fpr=`gpg --with-colons --fingerprint <user-id> |awk -F: '$1 == "fpr" {print$10; exit}'`
gpg --export-ownertrust && echo $fpr:6: |gpg --import-ownertrust

在这里,我假设你使用<user-id.keyfile>中的<user-id>导入了一个密钥。第二行仅提取指纹,如果您事先知道指纹,则可以放弃它。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接