通过Bouncy Castle提取GPG密钥使用标志

3
似乎PGPPublicKey类提供了一个isEncryptionKey()方法,用于确定公钥算法是否可用于加密目的(RSA_GENERAL, RSA_ENCRYPT, ELGAMAL_GENERAL, ELGAMAL_ENCRYPT),但仅此还不足以选择有效的加密子密钥。
公钥的预期使用信息存储在数据包中,如GnuPG packet.h所示。
 41 /* Usage flags */
 42 #define PUBKEY_USAGE_SIG     GCRY_PK_USAGE_SIGN  /* Good for signatures. */
 43 #define PUBKEY_USAGE_ENC     GCRY_PK_USAGE_ENCR  /* Good for encryption. */
 44 #define PUBKEY_USAGE_CERT    GCRY_PK_USAGE_CERT  /* Also good to certify keys.*/
 45 #define PUBKEY_USAGE_AUTH    GCRY_PK_USAGE_AUTH  /* Good for authentication. */
 46 #define PUBKEY_USAGE_UNKNOWN GCRY_PK_USAGE_UNKN  /* Unknown usage flag. */
 47 #define PUBKEY_USAGE_NONE    256                 /* No usage given. */

我的问题是,考虑到Bouncy Castle没有暴露这些标志,从Java中的PublicKeyPacket中提取此键用法信息的建议方法是什么?

1个回答

8

我找到了解决方法。为了后人,以下是解决方案:

// If Key Usage flags are present, we must respect them:
int keyFlagsEncountered = 0;
boolean keyUsageAllowsEncryption = false;

Iterator<PGPSignature> i = key.getSignatures();
while(i.hasNext()) {
    PGPSignature signature = i.next();
    int keyFlags = signature.getHashedSubPackets().getKeyFlags();
    keyFlagsEncountered += keyFlags;

    boolean isEncryptComms = (keyFlags & KeyFlags.ENCRYPT_COMMS) > 0;
    boolean isEncryptStorage = (keyFlags & KeyFlags.ENCRYPT_STORAGE) > 0;
    // Other KeyFlags available here (AUTHENTICATION, SIGN_DATA, CERTIFY_OTHER).

    if (isEncryptComms || isEncryptStorage) {
        keyUsageAllowsEncryption = true;
    }
}

// However, if Key Usage flags are not present (older key, or key generation process simply did not include the flags) 
// then we still attempt to use an encryption key using the existing methods:
keyUsageAllowsEncryption = keyFlagsEncountered == 0 || keyUsageAllowsEncryption;

1
来自后代的问候。应该是 keyFlags&KeyFlags.ENCRYPT_COMMS == 0 而不是> 0 吗?谢谢。 - Lazarus

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