Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

jpgpj cannot decode GPG2 .kbx ("keybox") rings #21

Closed
lgoldstein opened this issue Nov 28, 2018 · 6 comments
Closed

jpgpj cannot decode GPG2 .kbx ("keybox") rings #21

lgoldstein opened this issue Nov 28, 2018 · 6 comments
Assignees

Comments

@lgoldstein
Copy link

I generated and populated a key ring using Linux gpg2 commands. When loading the pubring.kbx (in this case) there is no error, but the ring is reported as empty (which I can assure you it isn't):

Ring ring;
try (InputStream stream = Files.newInputString("/path/to/pubring.kbx")) {
    ring = new Ring(stream);
}
Collection<Key> keys = ring.getKeys();   // returns empty list

If you wish, I can send you a zip of the generated key-ring files for inspection and analysis (since they were for a test I don't really need them), though I believe the issue is easily reproducible. Seems to be some kind of version issue, since I can successfully load/read my $HOME/.gnunpg/pubring.gpg file. I did verify that version 1.x rings are correctly decoded, so I assume that my real ring was once 1.x and converted to 2.x, but the conversion left it somehow backward compatible.

@justinludwig justinludwig self-assigned this Nov 28, 2018
@justinludwig
Copy link
Owner

Thanks for raising this issue! JPGPJ currently doesn't support reading keys from the gpg2 "kbx" (aka "keybox") file format. However, I believe Bouncy Castle (the underlying crypto library that JPGPJ uses) recently added some tools for reading these kind of files, so it should be possible to update JPGPJ to pull the public keys out of "keybox" files. I'll leave this issue open as a placeholder for adding that functionality (and also tweak the issue title to help remind myself about it).

In the meantime, if you need to use new keys that are only stored in a .kbx file, you can work around it by using gpg2 to first export the keys from the keybox to a traditional keyring like this:

gpg2 --keyring /path/to/pubring.kbx --export > /path/to/pubring.gpg

And then JPGPJ should be able to load the exported keys from /path/to/pubring.gpg like normal.

@justinludwig justinludwig changed the title jpgpj cannot always decode GPG2 generated rings - probably 2.x vs 1.x issue jpgpj cannot decode GPG2 .kbx ("keybox") rings Nov 28, 2018
@lgoldstein
Copy link
Author

Thanks for the quick reply and workaround. BTW, great library - makes working with PGP keys relatively easy - see MINA SSHD - keep up the good work.

justinludwig added a commit that referenced this issue Feb 21, 2019
When loading keys into a ring from a file or stream, automatically
detect if the file/stream uses the gpg "kbx" (aka keybox) format,
and use the new bouncy castle 1.61 keybox apis to load all the public
keys from that keybox.
@justinludwig
Copy link
Owner

I just released a new version of JPGPJ (0.6.1) that should be able load public keys from a "kbx" file, just like you'd expect. Let me know if you run into any issues with it.

@lgoldstein
Copy link
Author

Great - I'll look, into it soon and open a new issue if I find any problems...

@bclark76
Copy link

bclark76 commented Oct 4, 2019

I did:

$ gpg2 --keyring /path/to/pubring.kbx --export > /path/to/pubring.gpg
$ gpg2 --keyring /path/to/pubring.kbx --export-secret-keys > /path/to/secring.gpg

and this seems to work fine. I can use those files as my public key file and my secret key file the way I had been.

I can use the .kbx file for public keys too.

But as for the secret keys, no luck. I cannot pass pubring.kbx as they secret key file, and so signing while encrypting also doesn't work that way.

Trying to remain compatible with using gpg2 maintained .gnupg/ directory. ATM, being able to export keys into .gpg format is good enough, but I wonder if it will be possible to use secret keys from a /home/username/.gnupg/ directory without asking admins to do an export step whenever they update something...

As for me, they haven't updated to .kbx format yet so I still have .gpg ring files to use anyway, but the day may come when there's just .kbx files.

@justinludwig
Copy link
Owner

That's a good point -- I hadn't really thought about the issue of trying to suck in all the secret keys from a .gnupg directory before. With gpg2, the secret key material is stored separately from the public key information, with the secret key material for each subkey stored as a separate .key file in the .gnupg/private-keys-v1.d directory -- that's why JPGPJ currently only uses the public part of keys when loading from a .kbx file.

It'd be some work to add support for loading these gpg2 secret .key files, and matching them up with the public key info from a .kbx file; but it would be nice if you could just point JPGPJ at a directory and have it load up all available keys from it, like say:

Ring ring = new Ring(new File("path/to/.gnupg"));
KeyForSigning signingKey = new KeyForSigning(ring.findAll("alice").get(0), "password123");
KeyForEncryption encryptionKey = new KeyForEncryption(ring.findAll("bob").get(0));
new Encryptor(signingKey, encryptionKey).encrypt(
    new File("plain.txt"),
    new File("cipher.txt.gpg")
);

or:

Ring ring = new Ring(new File("path/to/.gnupg"));
ring.findAll("bob").get(0).setPassphrase("b0bru1z!");
new Decryptor(ring).decrypt(new File("cipher.txt.gpg"), new File("plain.txt"));

Also, it would be nice if you could call out specific .kbx and .key files to load into a JPGPJ ring:

Ring ring = new Ring(
    new File("path/to/pubring.kbx"),
    new File("path/to/1234ABCD.key"),
    new File("path/to/5678EF90.key"),
    new File("path/to/ABCD1234.key"),
    new File("path/to/EF905789.key")
);

Or load the .key file for just a specific subkey:

Ring ring = new Ring(new File("path/to/pubring.kbx"));
Key alice = ring.findAll("0x1234ABCD").get(0);
Subkey signingKey = alice.findAll("0x1234ABCD").get(0);
signingKey.loadSecretKey(new File("path/to/alice-signing.key"));
signingKey.setPassphrase("password123");

I'll open up a new issue specifically for loading gpg2 secret keys (with the intent of implementing support for it in the future).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants