Search code examples
javabouncycastle

Load multiple public keys from single file with Bouncy Castle PGP


I have a text file which contains several ASCII-armored OpenPGP public keys. I want to use Bouncy Castle to encrypt a string to all the public keys contained in this file. However, when I load the file into a PGPPublicKeyRingCollection, only the first key is returned:

private static List<PGPPublicKey> readPublicKeys(InputStream input) throws IOException, PGPException {
    PGPPublicKeyRingCollection pgpPub = new PGPPublicKeyRingCollection(PGPUtil.getDecoderStream(input), new JcaKeyFingerprintCalculator());
    List<PGPPublicKey> keys = new ArrayList<>();

    // size is 1 here
    logger.debug("size " + pgpPub.size());
    @SuppressWarnings("unchecked")
    Iterator<PGPPublicKeyRing> keyRingIter = pgpPub.getKeyRings();
    while (keyRingIter.hasNext()) {
        PGPPublicKeyRing keyRing = keyRingIter.next();

        @SuppressWarnings("unchecked")
        Iterator<PGPPublicKey> keyIter = keyRing.getPublicKeys();
        while (keyIter.hasNext()) {
            PGPPublicKey key = keyIter.next();

            // there is only ever 1 key here as well
            if (key.isEncryptionKey()) {
                keys.add(key);
            }
        }
    }

    if (keys.size() > 0) {
        return keys;
    } else {
        throw new IllegalArgumentException("Can't find encryption key in key ring.");
    }
}

Am I missing something?

FWIW, when I run $ gpg --dry-run my.keys, it correctly detects all 7 public keys and outputs their fingerprints.


Solution

  • I don't know if you finally found an answer to this question or not, but I had the same issue. If I export multiple keys from gpg on the command line:

    gpg --export --armor 374ABFC6 B3E4E0A5 > combined.public.asc
    

    And then created an InputStream for that file, Bouncy Castle was able to import both of those keys without any problems.

    It may not be helpful if your keys are coming from elsewhere, but the public key InputStream you have is not encoded correctly (I'm assuming since it's only grabbing the first key) to contain multiple keys. If I just concatenate two PGP key blocks into the same file, then it only ever reads the first key. After exporting like above, the combined.public.asc file only has one giant PGP key block.