KeySelectionStrategy that receive keys
herbertpimentel opened this issue · 5 comments
I cant find a way to define a keystregy any other beyond by email, this is a problem because I don't know name ID of the key sent to me. I only need to use this public key to encrypt to my sender.
In the end would be awesome have an option to KeySelectionStrategy such as:
byte[] myOwnPrivateKey = DB.getMyPrivateKey();
byte[] customerPublicKey = DB.getCustomerPrivateKey();
final OutputStream encryptionStream = BouncyGPG
.encryptToStream()
.toRecipient(customerPublicKey)
.andSignWith(myOwnPrivateKey)
.armorAsciiOutput()
.andWriteTo(buffer);
I am sorry, this may is a stupid question but I really don't know how to deal with it.
The easiest way to to that would be to use the InMemoryKeyring
and call getPublicKeyRings()
/ getSecretKeyRings()
.
Then, to Demeters utmost horror, call .getKeyRings().next().getSecretKey().getUserIDs().next()
to get the user Ids of the keys.
If this does not work reliably (e.g. you cannot distinguish your and the customers key) have a look at the source code that parses the keys.
@herbertpimentel , try this. The (ugly..) magic is in firstUidForKeyRings(...)
. The rest is standard encryption.
/**
* Send a message by extracting the userIds from the keys themselves.
*/
@Test
public void extractingUserIdFromKeyExample()
throws IOException, PGPException, NoSuchAlgorithmException, SignatureException, NoSuchProviderException {
// sender needs his own public and private key, and the recipients public kjey
final byte[] recipientPubKey = ExampleMessages.PUBKEY_RECIPIENT.getBytes();
final byte[] senderPublicKey = ExampleMessages.PUBKEY_SENDER.getBytes();
final byte[] senderPrivateKey = ExampleMessages.SECRET_KEY_SENDER.getBytes();
final String senderPrivateKeyPassphrase = "sender";
// Prepare the keyring
final InMemoryKeyring keyring = KeyringConfigs
.forGpgExportedKeys(KeyringConfigCallbacks.withPassword(senderPrivateKeyPassphrase));
keyring.addPublicKey(recipientPubKey);
keyring.addSecretKey(senderPrivateKey);
// at this stage the public keyring, and the private keyring contain only ONE key
final String sendersPrivateKeyUserId = firstUidForKeyRings(keyring.getSecretKeyRings());
final String recipientsPublicKeyUserId = firstUidForKeyRings(keyring.getPublicKeyRings());
// Hack: we add the senders public key after extracting the recipients userid
// Alternatively we could parse the keys "ba hand"
keyring.addPublicKey(senderPublicKey);
final ByteArrayOutputStream encryptedData = new ByteArrayOutputStream();
try (
final OutputStream encryptionStream = BouncyGPG
.encryptToStream()
.withConfig(keyring)
.withStrongAlgorithms()
.toRecipient(recipientsPublicKeyUserId)
.andSignWith(sendersPrivateKeyUserId)
.armorAsciiOutput()
.andWriteTo(encryptedData);
final ByteArrayInputStream plaintext = new ByteArrayInputStream("Hello world".getBytes())
) {
Streams.pipeAll(plaintext, encryptionStream);
}
encryptedData.close();
byte[] chipertext = encryptedData.toByteArray();
}
/*
* return the first userid of the first key in the first keyring.
*/
private String firstUidForKeyRings(Iterable<? extends PGPKeyRing> keyRings) {
// Watch Demeters Law scream in agony
final Iterator<? extends PGPKeyRing> keyRingIterator = keyRings.iterator();
final PGPKeyRing firstKeyRing = keyRingIterator.next();
assertFalse("Not stable with more than one keyring",keyRingIterator.hasNext());
final PGPPublicKey firstKeyInFirstKeyring = firstKeyRing.getPublicKey();
// any userid of this key will suffice
return firstKeyInFirstKeyring.getUserIDs().next();
}
@herbertpimentel : did you get a chance to try the workaround?
@herbertpimentel : did you get a chance to try the workaround?
Sorry, I will try it out. But I have accomplished my task using a product library.
Closing due to no reply