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

No (suitable) public key for encryption to [a provided recipient email address] found #50

Open
michaelthecsguy opened this issue Apr 3, 2020 · 14 comments

Comments

@michaelthecsguy
Copy link

michaelthecsguy commented Apr 3, 2020

Hi,

I tested encryption out with gpg in commandline with no problem. When I test it out with Bouncy-gpg by using this code:

    publicKeyLocation = "../GPGKeys/Experian/Experian_Public.asc";
    final String PUBLIC_KEY = new String(Files.readAllBytes(Paths.get(publicKeyLocation)));
    gpgFileLocation = "../Development/treadstone/test.gpg";
    FileOutputStream fileOutput = new FileOutputStream(gpgFileLocation);
    BufferedOutputStream bufferedOutputStream = null;
    FileInputStream fis = null;
    OutputStream outputStream = null;
    InMemoryKeyring keyring = 
    KeyringConfigs.forGpgExportedKeys(KeyringConfigCallbacks.withUnprotectedKeys());
    String UID = "Data.File@experian.com";
    keyring.addPublicKey(PUBLIC_KEY.getBytes(StandardCharsets.US_ASCII));

    try {
      bufferedOutputStream = new BufferedOutputStream(fileOutput);
      fis = new FileInputStream(plainFileLocation);
      outputStream = BouncyGPG
        .encryptToStream()
        .withConfig(keyring)
        .withStrongAlgorithms()
        .toRecipient(UID)
        .andDoNotSign()
        .binaryOutput()
        .andWriteTo(bufferedOutputStream);
      Streams.pipeAll(fis, outputStream);

    } catch (Exception ex) {
      throw new RuntimeException(ex);
    } finally {
      if (bufferedOutputStream != null && fis != null && outputStream != null) {
        outputStream.close();
        bufferedOutputStream.close();
        fileOutput.close();
      }
    }

Then, It gives exception

java.lang.RuntimeException: org.bouncycastle.openpgp.PGPException: No (suitable) public key for encryption to Data.File@experian.com found
	at com.viantinc.BouncyGPGTest.testEncryptionByUsingPubKeyWithTryCatch(BouncyGPGTest.java:165)
...
...
...
Caused by: org.bouncycastle.openpgp.PGPException: No (suitable) public key for encryption to Data.File@experian.com found
	at name.neuhalfen.projects.crypto.bouncycastle.openpgp.BuildEncryptionOutputStreamAPI$WithAlgorithmSuiteImpl$ToImpl.extractValidKey(BuildEncryptionOutputStreamAPI.java:414)
	at name.neuhalfen.projects.crypto.bouncycastle.openpgp.BuildEncryptionOutputStreamAPI$WithAlgorithmSuiteImpl$ToImpl.toRecipient(BuildEncryptionOutputStreamAPI.java:431)
	at com.viantinc.BouncyGPGTest.testEncryptionByUsingPubKeyWithTryCatch(BouncyGPGTest.java:158)

This code works all other public key except this one. The interesting part is that it works in GPG commandline.

I have attached the public key in the following comment. I don't know if the recipient email address the "dot" in front of domain that causes the issue.

@michaelthecsguy
Copy link
Author

ExperianPubKey.txt

@neuhalje neuhalje self-assigned this Apr 5, 2020
@michaelthecsguy
Copy link
Author

just FYI, right now for short term solution, I just use Java subprocess to call python's gnupg library to do encryption. Once this is fixed, I will test it for you and will use it.

@mdesmons
Copy link
Contributor

mdesmons commented Apr 27, 2020

I had the same issue. Checking the content of your key with:
gpg --export -a <key id>|gpg --list-packets --verbose

the key doesn't contain a KeyFlags subpacket (subpacket type 27). This section of the key indicates whether the key can be used for encryption, or signing, or other things.

In this case Bouncy-gpg assumes the key cannot be used for encryption.
GPG is more lenient: if a key doesn't contain a KeyFlags subpacket, it will check the key algo, and if the algo is for example RSA, it assumes the key is fine for encrypting/signing

An alternative to using a python call is to implement your own KeySelectionStrategy, so that it accepts keys that don't explicitly have an Encryption flag

I attached an example for reference, which mimics GPG behaviour
CustomKeySelectionStrategy.zip

mdesmons added a commit to mdesmons/bouncy-gpg that referenced this issue Apr 28, 2020
@mdesmons
Copy link
Contributor

Entered PR52 to fix the issue

@michaelthecsguy
Copy link
Author

@neuhalje or @mdesmons, is the fix merged to the next build? and new Jar version?

I am ready to test it.

@mdesmons
Copy link
Contributor

It doesn't look like it's been merged yet. I don't have write access to the repo and can only submit a PR, I think @neuhalje has to review and approve...

But my comment above provides a workaround that doesn't require changing the library, if you really need it
#50 (comment)

@jonathan609
Copy link

Can you provide an example of how to use the override with InMemoryKeyring?

Not sure how to implement the override when the parent class is not an explicit instantiation.

For example where to override the single use of "KeyringConfigCallbacks" below?

keyring = KeyringConfigs.forGpgExportedKeys(KeyringConfigCallbacks.withPassword(passphrase));
keyring.addPublicKey(publicKey.getBytes("US-ASCII"));
keyring.addSecretKey(privateKey.getBytes("US-ASCII"));

BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(result);
OutputStream outStream = BouncyGPG.encryptToStream()
.withConfig(keyring)
.withStrongAlgorithms()
.toRecipient(receiverUserId)
.andSignWith(senderUserIdEmail)
.armorAsciiOutput()
.andWriteTo(bufferedOutputStream)

@neuhalje
Copy link
Owner

neuhalje commented Jul 1, 2020

I’ll look into that shortly

neuhalje added a commit that referenced this issue Jul 12, 2020
…mdesmons-master

* 'master' of https://github.com/mdesmons/bouncy-gpg:
  added comment to extractPublicKeyFlags
  Fix for issue #50, where we cannot encrypt if a key doesn't have a KeyFlags subpacket
neuhalje added a commit that referenced this issue Jul 12, 2020
* mdesmons-master:
  added comment to extractPublicKeyFlags
  Fix for issue #50, where we cannot encrypt if a key doesn't have a KeyFlags subpacket
@neuhalje
Copy link
Owner

Please check - should be fixes

@trvi-ncs
Copy link

Hi there! Was this ever put through? Getting the same issue here. Thanks!

@brad-az
Copy link

brad-az commented Oct 19, 2021

Same question here.

@jayadatta
Copy link

jayadatta commented Jun 3, 2022

Same question here.

Hi there! Was this ever put through? Getting the same issue here. Thanks!

we were able to resolve it by invoking selectUidByAnyUidPart() after initializing WithKeySelectionStrategy.

ex: outputStream = BouncyGPG
.encryptToStream()
.withConfig(keyring).selectUidByAnyUidPart()
.withStrongAlgorithms()
.toRecipient(UID)
.andDoNotSign()
.binaryOutput()
.andWriteTo(bufferedOutputStream);
Streams.pipeAll(fis, outputStream);

@ckerndev
Copy link

ckerndev commented Jul 7, 2023

Same question here.
Hi there! Was this ever put through? Getting the same issue here. Thanks!

@jorgenmeedom
Copy link

Is this still a problem?
I get message "PGPException: No (suitable) public key for encryption to xxx@yyy.dk found" when I add the recipient xxx@yyy.dk to BouncyGPG using .toRecipient("xxx@yyy.dk").
Why do BouncyGPG check on toRecipient? I should think this is the job of the recipient service to check that he is identical to "xxx@yyy.dk".

@michaelthecsguy michaelthecsguy removed their assignment Sep 20, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

9 participants