justinludwig / jpgpj

Java Pretty Good Privacy Jig
MIT License
74 stars 20 forks source link

Handle case where master key can be used for encryption to match gpg #16

Closed ntbrock closed 5 years ago

ntbrock commented 6 years ago

Justin,

Wonderful project! I've been a gpg user for years and have some specific cases where I am encrypting data using the parent key, not just subkeys.

Could you advise on a more elegant way to support this use case? I'm new to your codebase.

Taylor

justinludwig commented 6 years ago

Thanks for the feedback! PGPPublicKey.isEncryptionKey() just indicates whether or not the key technically could be used for encryption, not whether or not it was flagged to be used that way (most people's certification/signing keys could also technically be used for encryption). To ignore the key's usage flags, you can manually set the forDecryption flag on the key after you load it, and JPGPJ will use it for decryption whenever it runs across a message encrypted with it. Here's an example:

https://github.com/justinludwig/jpgpj/wiki/DecryptingFiles#decryption-subkey-not-flagged

justinludwig commented 5 years ago

Thanks again for raising this issue! In JPGPJ 0.7, I added some new classes that I think will make the library easier to use in cases like this.

There's a new KeyForDecryption class that you can use in place of the regular Key class to load a key and flag all of its subkeys (including the master/parent key) to be used for decryption; and a KeyForVerification class that you can use to load a key and flag all of its subkeys to be used for verification. Here's an example (of decrypting a message with Alice's key, and verifying it with Bob's key):

new Decryptor(
    new KeyForDecryption(new File("path/to/my/keys/alice-sec.gpg"), "password123"),
    new KeyForVerification(new File("path/to/my/keys/bob-pub.gpg"))
).decrypt(
    new File("path/to/ciphertext.txt.gpg"),
    new File("path/back-to/plaintext.txt")
);

If you need to decrypt and verify with the same key, you can just load up the same key twice, once with the KeyForDecryption class (unlocking the secret key with a passphrase), and once with the KeyForVerification class (which doesn't use the passphrase):

new Decryptor(
    new KeyForDecryption(new File("path/to/my/keys/alice-sec.gpg"), "password123"),
    new KeyForVerification(new File("path/to/my/keys/alice-sec.gpg"))
).decrypt(
    new File("path/to/ciphertext.txt.gpg"),
    new File("path/back-to/plaintext.txt")
);