How to use public key OpenPGP(GPG) without access to physical key ring in Java

1.9k views Asked by At

Setup:

  • Linux with GnuPG or Windows with GPG4Win(OpenPGP)
  • A 2048 RSA keypair has been created by a privileged user who can access the key ring
  • A second lower privilege user has been created for a java application to run under
  • Permission has been granted for this user to run GPG commands but cannot access physical key ring files
  • The key IDs are known to the java application and so is the passphrase to extract private key
  • Java application has imported Bouncycastle library
  • The java program needs to perform an encryption and decryption using the key pair

Problem:

I have successfully performed encryption and decryption using Bouncycastle. But it involved trying to read the public and private keys from the pubring and secring files. For security, I would rather not have the java application have direct access to the key ring files.

What are my options. Are there any options in Bouncycastle to do this without reading the key rings or exporting the keys to separate files?

Note: Using Bouncy castle is not necessary.

2

There are 2 answers

1
tucuxi On

Your Java application can call gnupg with whatever privileges the user that executes the application currently has. Fortunately, gnupg supports a wealth of command-line options that allow you to supply all necessary arguments and read/collect back status and results, such as -batch, -options or -status-fd. You can call programs from Java and read their results back using Java's ProcessBuilder or higher level libraries such as Plexus Utils

On the other hand, there is at least one java-based wrapper library that speaks directly with the GnuPG executable. While platform-dependent, this probably has speed advantages over spawning a process for each transaction; and will probably spare you a lot of implementation effort figuring out command-line options.

Note that using GnuPG this way bypasses BouncyCastle entirely -- you would be automating calls to GnuPG, effectively using it as your "library".

3
Jens Erat On

BouncyCastle requires direct access to the key files, both the public and private keys.

Not Using BouncyCastle

If you want to prevent the Java application from accessing the key files, but still use it for encryption and decryption, you might be successful using GnuPG 2.1 which offloads all operation requiring access to the private keyring to the gpg-agent. A setup that might work would look somewhat like that:

  • Start gpg-agent
  • Restrict access for your Java application, so it can access the gpg-agent socket, but not the private key files

In Linux, you might consider using chroot or appropriate permissions for the socket and keyring files. In Windows, there might be something like a sandbox solution.

Building your own BouncyCastle Daemon

Similar to the small-weight gpg-agent, you could write your own daemon that handles all secret key operations, while not exposing the key at the same time (so you've got a small daemon with much lower chance of critical bugs; while the large, possibly insecure and exposed main application can send requests for encryption/decryption to the "agent" application).