为什么 gpg --encrypt 会因密钥标志为 0x0C 且永不过期的子密钥数据包而失败?

Why gpg --encrypt fails with sub key packet with key flags 0x0C that never expires?

当我分析那个 gpg --list-packets 输出的输出时,我发现子密钥包永不过期,它的 key flags0C 对应 "Encryption"。 (见底部的输出。)

public 密钥包已经过期,但它的 key flags03 代表 "Key Certification" | "Sign Data",因此不需要加密。

然而当我 运行 gpg --always-trust -r user@user.com --encrypt abc 我得到这个错误:

gpg: user@user.com: skipped: unusable public key
gpg: abc: encryption failed: unusable public key

为什么会这样?为什么 "never expire" 加密密钥在这种情况下不可用?是不是publickey过期了,不管key flags是什么,所有子key自动失效?

这是 gpg --list-packets user.public.key 的输出:

gpg: WARNING: using insecure memory!
gpg: please see http://www.gnupg.org/faq.html for more information
:public key packet:
        version 4, algo 1, created 1471460125, expires 0
        pkey[0]: [2048 bits]
        pkey[1]: [17 bits]
:user ID packet: "userid <user@user.com>"
:signature packet: algo 1, keyid A5038DC251BC03DC
        version 4, created 1471460130, md5len 0, sigclass 0x13
        digest algo 2, begin of digest c4 fa
        hashed subpkt 2 len 4 (sig created 2016-08-17)
        hashed subpkt 9 len 4 (key expires after 2y0d0h0m)
        hashed subpkt 27 len 1 (key flags: 03)
        hashed subpkt 11 len 7 (pref-sym-algos: 2 3 4 7 8 9 10)
        hashed subpkt 22 len 4 (pref-zip-algos: 2 1 0 3)
        hashed subpkt 25 len 1 (primary user ID)
        subpkt 16 len 8 (issuer key ID A5038DC251BC03DC)
        data: [2046 bits]
:public sub key packet:
        version 4, algo 1, created 1471460125, expires 0
        pkey[0]: [2048 bits]
        pkey[1]: [17 bits]
:signature packet: algo 1, keyid A5038DC251BC03DC
        version 4, created 1471460131, md5len 0, sigclass 0x18
        digest algo 2, begin of digest 7f 63
        hashed subpkt 2 len 4 (sig created 2016-08-17)
        hashed subpkt 27 len 1 (key flags: 0C)
        subpkt 16 len 8 (issuer key ID A5038DC251BC03DC)
        data: [2042 bits]

经过进一步分析,我得出以下结论:

我没有使用 gpg --list-packets,而是使用 gpg --with-colon,并从输出中获取第一个 pub 键。我注意到如果 pub 密钥没有过期那么它总是允许加密。如果 pub 已过期,那么 sub 是什么并不重要 - 密钥已过期并且 gpg 拒绝加密。

具有过期子密钥的永不过期 public 密钥示例(使用 gpg --with-colon user.public.key

pub:-:3072:1:BFDEF66008072C77:2016-08-21:::-:userid <user@user.com>:
sub:-:3072:1:1AF28CF198A6BEA3:2016-08-21:2018-08-21::: [expires: 2018-08-21]
sub:-:3072:1:DA2B5429D88156C7:2016-08-21:2016-08-26::: [expires: 2016-08-26]

这个将允许加密。

在此处查看如何处理此输出的详细信息:

https://git.gnupg.org/cgi-bin/gitweb.cgi?p=gnupg.git;a=blob_plain;f=doc/DETAILS

的例子