OpenPGP 加密密钥 - isValidForEncrypting()?

OpenPGP encryption key - isValidForEncrypting()?

我正在查看 some code of MyPGP 以检查 OpenPGP 密钥是否对加密有效。 RFC 4880 帮助我稍微理解了代码。但是鉴于我对签名类型没有很好的了解,我无法清楚地理解以下代码段:

 private static boolean hasKeyFlags(PGPPublicKey key, int keyUsage) {
    if (key.isMasterKey()) {
        for (int certificationType : MASTER_KEY_CERTIFICATION_TYPES) {
            Iterator eIt = key.getSignaturesOfType(certificationType);
            while (eIt.hasNext()) {
                PGPSignature signature = (PGPSignature) eIt.next();
                if (!isMatchingUsage(signature, keyUsage))
                    return false;
            }
        }
    } else {
        Iterator eIt = key.getSignaturesOfType(PGPSignature.SUBKEY_BINDING);
        while (eIt.hasNext()) {
            PGPSignature signature = (PGPSignature) eIt.next();
            if (!isMatchingUsage(signature, keyUsage))
                return false;
        }
    }
    return true;
   }

哪里

 private static final int[] MASTER_KEY_CERTIFICATION_TYPES = new int[]{
        PGPSignature.POSITIVE_CERTIFICATION,
        PGPSignature.CASUAL_CERTIFICATION,
        PGPSignature.NO_CERTIFICATION,
        PGPSignature.DEFAULT_CERTIFICATION
};

我不确定为什么我们要寻找主密钥的特定签名类型,否则为什么要研究 SUBKEY_BINDINGs。

密钥使用标志和自签名

主(“主”)和子密钥在自签名中定义了它们的使用标志,可以是不同的签名类型(来自RFC 4880, 5.2.3.3. Notes on Self-Signatures

There are three types of self-signatures, the certification signatures (types 0x10-0x13), the direct-key signature (type 0x1F), and the subkey binding signature (type 0x18).

代码

对于主键,使用类型 0x10-0x13(这是函数第一个分支中 MASTER_KEY_CERTIFICATION_TYPES 的循环)。对于子密钥,使用标志始终存储在类型为 0x18 的子密钥绑定签名中。在第二个分支中检查。

由于可以有多个自签名,作者循环遍历了所有的自签名。我没有完全阅读代码,但不确定他是否符合RFC 4880,我认为他应该使用newest non-revoked self signature;可能是他用的是第一个匹配的(不管是被取代还是被撤销)。

查看密钥

您可以使用类似

的命令验证密钥使用标志的存储位置
gpg --export-options export-minimal --export 0xdeadbeef | gpg --list-packets

查找以 hashed subpkt 27 开头的行,这些行表示密钥使用标志设置。 sigclass 列在上面一点点。 gpg --list-packets 输出几乎不可读,并且包含许多要在 RFC 4880 中查找的数字引用,但您似乎已经对 RFC 有点熟悉了。