diff --git a/pgpainless-core/src/main/java/org/pgpainless/encryption_signing/EncryptionOptions.java b/pgpainless-core/src/main/java/org/pgpainless/encryption_signing/EncryptionOptions.java index ed6dbf0e..34adacdd 100644 --- a/pgpainless-core/src/main/java/org/pgpainless/encryption_signing/EncryptionOptions.java +++ b/pgpainless-core/src/main/java/org/pgpainless/encryption_signing/EncryptionOptions.java @@ -15,10 +15,12 @@ */ package org.pgpainless.encryption_signing; +import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashSet; +import java.util.List; import java.util.Map; import java.util.Set; @@ -32,15 +34,46 @@ import org.pgpainless.key.SubkeyIdentifier; import org.pgpainless.key.info.KeyRingInfo; import org.pgpainless.util.Passphrase; +/** + * Options for the encryption process. + * This class can be used to set encryption parameters, like encryption keys and passphrases, algorithms etc. + * + * A typical use might look like follows: + *
+ * {@code
+ * EncryptionOptions opt = new EncryptionOptions();
+ * opt.addRecipient(aliceKey, "Alice ");
+ * opt.addPassphrase(Passphrase.fromPassword("AdditionalDecryptionPassphrase123"));
+ * }
+ * 
+ * + * To use a custom symmetric encryption algorithm, use {@link #overrideEncryptionAlgorithm(SymmetricKeyAlgorithm)}. + * This will cause PGPainless to use the provided algorithm for message encryption, instead of negotiating an algorithm + * by inspecting the provided recipient keys. + * + * By default, PGPainless will only encrypt to a single encryption capable subkey per recipient key. + * This behavior can be changed, eg. by calling + *
+ * {@code
+ * opt.addRecipient(aliceKey, EncryptionOptions.encryptToAllCapableSubkeys());
+ * }
+ * 
+ * when adding the recipient key. + */ public class EncryptionOptions { private final EncryptionStream.Purpose purpose; private final Set encryptionMethods = new LinkedHashSet<>(); private final Set encryptionKeys = new LinkedHashSet<>(); private final Map keyRingInfo = new HashMap<>(); + private final EncryptionKeySelector encryptionKeySelector = encryptToFirstSubkey(); private SymmetricKeyAlgorithm encryptionAlgorithmOverride = null; + /** + * Encrypt to keys both carrying the key flag {@link org.pgpainless.algorithm.KeyFlag#ENCRYPT_COMMS} + * or {@link org.pgpainless.algorithm.KeyFlag#ENCRYPT_STORAGE}. + */ public EncryptionOptions() { this(EncryptionStream.Purpose.STORAGE_AND_COMMUNICATIONS); } @@ -49,10 +82,22 @@ public class EncryptionOptions { this.purpose = purpose; } + /** + * Factory method to create an {@link EncryptionOptions} object which will encrypt for keys + * which carry the flag {@link org.pgpainless.algorithm.KeyFlag#ENCRYPT_COMMS}. + * + * @return encryption options + */ public static EncryptionOptions encryptCommunications() { return new EncryptionOptions(EncryptionStream.Purpose.COMMUNICATIONS); } + /** + * Factory method to create an {@link EncryptionOptions} object which will encrypt for keys + * which carry the flag {@link org.pgpainless.algorithm.KeyFlag#ENCRYPT_STORAGE}. + * + * @return encryption options + */ public static EncryptionOptions encryptDataAtRest() { return new EncryptionOptions(EncryptionStream.Purpose.STORAGE); } @@ -64,14 +109,32 @@ public class EncryptionOptions { * @param key key ring * @param userId user id */ - public void addRecipient(PGPPublicKeyRing key, String userId) { + public EncryptionOptions addRecipient(PGPPublicKeyRing key, String userId) { + return addRecipient(key, userId, encryptionKeySelector); + } + + /** + * Add a recipient by providing a key and recipient user-id, as well as a strategy for selecting one or multiple + * encryption capable subkeys from the key. + * + * @param key key + * @param userId user-id + * @param encryptionKeySelectionStrategy strategy to select one or more encryption subkeys to encrypt to + */ + public EncryptionOptions addRecipient(PGPPublicKeyRing key, String userId, EncryptionKeySelector encryptionKeySelectionStrategy) { KeyRingInfo info = new KeyRingInfo(key, new Date()); - PGPPublicKey encryptionSubkey = info.getEncryptionSubkey(userId, purpose); - if (encryptionSubkey == null) { - throw new AssertionError("Key has no encryption subkey."); + List encryptionSubkeys = encryptionKeySelectionStrategy + .selectEncryptionSubkeys(info.getEncryptionSubkeys(userId, purpose)); + if (encryptionSubkeys.isEmpty()) { + throw new AssertionError("Key has no suitable encryption subkeys."); } - addRecipientKey(key, encryptionSubkey); + + for (PGPPublicKey encryptionSubkey : encryptionSubkeys) { + addRecipientKey(key, encryptionSubkey); + } + + return this; } /** @@ -79,13 +142,30 @@ public class EncryptionOptions { * * @param key key ring */ - public void addRecipient(PGPPublicKeyRing key) { + public EncryptionOptions addRecipient(PGPPublicKeyRing key) { + return addRecipient(key, encryptionKeySelector); + } + + /** + * Add a recipient by providing a key and an encryption key selection strategy. + * + * @param key key ring + * @param encryptionKeySelectionStrategy strategy used to select one or multiple encryption subkeys. + */ + public EncryptionOptions addRecipient(PGPPublicKeyRing key, EncryptionKeySelector encryptionKeySelectionStrategy) { KeyRingInfo info = new KeyRingInfo(key, new Date()); - PGPPublicKey encryptionSubkey = info.getEncryptionSubkey(purpose); - if (encryptionSubkey == null) { - throw new IllegalArgumentException("Key has no encryption subkey."); + + List encryptionSubkeys = encryptionKeySelectionStrategy + .selectEncryptionSubkeys(info.getEncryptionSubkeys(purpose)); + if (encryptionSubkeys.isEmpty()) { + throw new IllegalArgumentException("Key has no suitable encryption subkeys."); } - addRecipientKey(key, encryptionSubkey); + + for (PGPPublicKey encryptionSubkey : encryptionSubkeys) { + addRecipientKey(key, encryptionSubkey); + } + + return this; } private void addRecipientKey(PGPPublicKeyRing keyRing, PGPPublicKey key) { @@ -100,13 +180,13 @@ public class EncryptionOptions { * * @param passphrase passphrase */ - public void addPassphrase(Passphrase passphrase) { + public EncryptionOptions addPassphrase(Passphrase passphrase) { if (passphrase.isEmpty()) { throw new IllegalArgumentException("Passphrase must not be empty."); } PBEKeyEncryptionMethodGenerator encryptionMethod = ImplementationFactory .getInstance().getPBEKeyEncryptionMethodGenerator(passphrase); - addEncryptionMethod(encryptionMethod); + return addEncryptionMethod(encryptionMethod); } /** @@ -119,8 +199,9 @@ public class EncryptionOptions { * * @param encryptionMethod encryption method */ - public void addEncryptionMethod(PGPKeyEncryptionMethodGenerator encryptionMethod) { + public EncryptionOptions addEncryptionMethod(PGPKeyEncryptionMethodGenerator encryptionMethod) { encryptionMethods.add(encryptionMethod); + return this; } public Set getEncryptionMethods() { @@ -141,4 +222,38 @@ public class EncryptionOptions { } this.encryptionAlgorithmOverride = encryptionAlgorithm; } + + public interface EncryptionKeySelector { + List selectEncryptionSubkeys(List encryptionCapableKeys); + } + + /** + * Only encrypt to the first valid encryption capable subkey we stumble upon. + * + * @return encryption key selector + */ + public static EncryptionKeySelector encryptToFirstSubkey() { + return new EncryptionKeySelector() { + @Override + public List selectEncryptionSubkeys(List encryptionCapableKeys) { + return encryptionCapableKeys.isEmpty() ? Collections.emptyList() : Collections.singletonList(encryptionCapableKeys.get(0)); + } + }; + } + + /** + * Encrypt to any valid, encryption capable subkey on the key ring. + * + * @return encryption key selector + */ + public static EncryptionKeySelector encryptToAllCapableSubkeys() { + return new EncryptionKeySelector() { + @Override + public List selectEncryptionSubkeys(List encryptionCapableKeys) { + return encryptionCapableKeys; + } + }; + } + + // TODO: Create encryptToBestSubkey() method } diff --git a/pgpainless-core/src/main/java/org/pgpainless/encryption_signing/SigningOptions.java b/pgpainless-core/src/main/java/org/pgpainless/encryption_signing/SigningOptions.java index b6f62063..870388b6 100644 --- a/pgpainless-core/src/main/java/org/pgpainless/encryption_signing/SigningOptions.java +++ b/pgpainless-core/src/main/java/org/pgpainless/encryption_signing/SigningOptions.java @@ -82,18 +82,21 @@ public final class SigningOptions { KeyRingInfo keyRingInfo = new KeyRingInfo(secretKey, new Date()); if (userId != null) { if (!keyRingInfo.isUserIdValid(userId)) { - throw new KeyValidationException(userId, keyRingInfo.getCurrentUserIdCertification(userId), keyRingInfo.getUserIdRevocation(userId)); + throw new KeyValidationException(userId, keyRingInfo.getLatestUserIdCertification(userId), keyRingInfo.getUserIdRevocation(userId)); } } - PGPPublicKey signingPubKey = keyRingInfo.getSigningSubkey(); - if (signingPubKey == null) { + List signingPubKeys = keyRingInfo.getSigningSubkeys(); + if (signingPubKeys.isEmpty()) { throw new AssertionError("Key has no valid signing key."); } - PGPSecretKey signingSecKey = secretKey.getSecretKey(signingPubKey.getKeyID()); - PGPPrivateKey signingSubkey = signingSecKey.extractPrivateKey(secretKeyDecryptor.getDecryptor(signingPubKey.getKeyID())); - List hashAlgorithms = keyRingInfo.getPreferredHashAlgorithms(userId, signingPubKey.getKeyID()); - addSigningMethod(secretKey, signingSubkey, hashAlgorithms.get(0), signatureType, false); + + for (PGPPublicKey signingPubKey : signingPubKeys) { + PGPSecretKey signingSecKey = secretKey.getSecretKey(signingPubKey.getKeyID()); + PGPPrivateKey signingSubkey = signingSecKey.extractPrivateKey(secretKeyDecryptor.getDecryptor(signingPubKey.getKeyID())); + List hashAlgorithms = keyRingInfo.getPreferredHashAlgorithms(userId, signingPubKey.getKeyID()); + addSigningMethod(secretKey, signingSubkey, hashAlgorithms.get(0), signatureType, false); + } } public void addDetachedSignature(SecretKeyRingProtector secretKeyDecryptor, @@ -111,18 +114,21 @@ public final class SigningOptions { KeyRingInfo keyRingInfo = new KeyRingInfo(secretKey, new Date()); if (userId != null) { if (!keyRingInfo.isUserIdValid(userId)) { - throw new KeyValidationException(userId, keyRingInfo.getCurrentUserIdCertification(userId), keyRingInfo.getUserIdRevocation(userId)); + throw new KeyValidationException(userId, keyRingInfo.getLatestUserIdCertification(userId), keyRingInfo.getUserIdRevocation(userId)); } } - PGPPublicKey signingPubKey = keyRingInfo.getSigningSubkey(); - if (signingPubKey == null) { + List signingPubKeys = keyRingInfo.getSigningSubkeys(); + if (signingPubKeys.isEmpty()) { throw new AssertionError("Key has no valid signing key."); } - PGPSecretKey signingSecKey = secretKey.getSecretKey(signingPubKey.getKeyID()); - PGPPrivateKey signingSubkey = signingSecKey.extractPrivateKey(secretKeyDecryptor.getDecryptor(signingPubKey.getKeyID())); - List hashAlgorithms = keyRingInfo.getPreferredHashAlgorithms(userId, signingPubKey.getKeyID()); - addSigningMethod(secretKey, signingSubkey, hashAlgorithms.get(0), signatureType, true); + + for (PGPPublicKey signingPubKey : signingPubKeys) { + PGPSecretKey signingSecKey = secretKey.getSecretKey(signingPubKey.getKeyID()); + PGPPrivateKey signingSubkey = signingSecKey.extractPrivateKey(secretKeyDecryptor.getDecryptor(signingPubKey.getKeyID())); + List hashAlgorithms = keyRingInfo.getPreferredHashAlgorithms(userId, signingPubKey.getKeyID()); + addSigningMethod(secretKey, signingSubkey, hashAlgorithms.get(0), signatureType, true); + } } private void addSigningMethod(PGPSecretKeyRing secretKey, diff --git a/pgpainless-core/src/main/java/org/pgpainless/key/info/KeyRingInfo.java b/pgpainless-core/src/main/java/org/pgpainless/key/info/KeyRingInfo.java index b4d1c9bf..fa874157 100644 --- a/pgpainless-core/src/main/java/org/pgpainless/key/info/KeyRingInfo.java +++ b/pgpainless-core/src/main/java/org/pgpainless/key/info/KeyRingInfo.java @@ -29,7 +29,6 @@ import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; -import org.bouncycastle.bcpg.sig.KeyFlags; import org.bouncycastle.bcpg.sig.PrimaryUserID; import org.bouncycastle.openpgp.PGPKeyRing; import org.bouncycastle.openpgp.PGPPublicKey; @@ -116,7 +115,7 @@ public class KeyRingInfo { * @return public key or null */ public PGPPublicKey getPublicKey(long keyId) { - return keys.getPublicKey(keyId); + return getPublicKey(keys, keyId); } /** @@ -143,12 +142,36 @@ public class KeyRingInfo { } if (publicKey == getPublicKey()) { + if (signatures.primaryKeyRevocation != null) { + if (SignatureUtils.isHardRevocation(signatures.primaryKeyRevocation)) { + return false; + } + } return signatures.primaryKeyRevocation == null; } PGPSignature binding = signatures.subkeyBindings.get(keyId); PGPSignature revocation = signatures.subkeyRevocations.get(keyId); - return binding != null && revocation == null; + + // No valid binding + if (binding == null || SignatureUtils.isSignatureExpired(binding)) { + return false; + } + + // Revocation + if (revocation != null) { + if (SignatureUtils.isHardRevocation(revocation)) { + // Subkey is hard revoked + return false; + } else { + if (!SignatureUtils.isSignatureExpired(revocation) && revocation.getCreationTime().after(binding.getCreationTime())) { + // Key is soft-revoked, not yet re-bound + return false; + } + } + } + + return true; } /** @@ -322,11 +345,13 @@ public class KeyRingInfo { } /** - * Return the current direct-key self signature. + * Return the latest direct-key self signature. * - * @return + * Note: This signature might be expired (check with {@link SignatureUtils#isSignatureExpired(PGPSignature)}). + * + * @return latest direct key self-signature */ - public PGPSignature getCurrentDirectKeySelfSignature() { + public PGPSignature getLatestDirectKeySelfSignature() { return signatures.primaryKeySelfSignature; } @@ -334,7 +359,7 @@ public class KeyRingInfo { return signatures.primaryKeyRevocation; } - public PGPSignature getCurrentUserIdCertification(String userId) { + public PGPSignature getLatestUserIdCertification(String userId) { return signatures.userIdCertifications.get(userId); } @@ -353,27 +378,28 @@ public class KeyRingInfo { public List getKeyFlagsOf(long keyId) { if (getPublicKey().getKeyID() == keyId) { - PGPSignature directKeySignature = getCurrentDirectKeySelfSignature(); + PGPSignature directKeySignature = getLatestDirectKeySelfSignature(); if (directKeySignature != null) { - KeyFlags flags = SignatureSubpacketsUtil.getKeyFlags(directKeySignature); - if (flags != null) { - return KeyFlag.fromBitmask(flags.getFlags()); + List keyFlags = SignatureSubpacketsUtil.parseKeyFlags(directKeySignature); + if (keyFlags != null) { + return keyFlags; } } String primaryUserId = getPrimaryUserId(); if (primaryUserId != null) { - KeyFlags flags = SignatureSubpacketsUtil.getKeyFlags(getCurrentUserIdCertification(primaryUserId)); - if (flags != null) { - return KeyFlag.fromBitmask(flags.getFlags()); + PGPSignature userIdSignature = getLatestUserIdCertification(primaryUserId); + List keyFlags = SignatureSubpacketsUtil.parseKeyFlags(userIdSignature); + if (keyFlags != null) { + return keyFlags; } } } else { PGPSignature bindingSignature = getCurrentSubkeyBindingSignature(keyId); if (bindingSignature != null) { - KeyFlags flags = SignatureSubpacketsUtil.getKeyFlags(bindingSignature); - if (flags != null) { - return KeyFlag.fromBitmask(flags.getFlags()); + List keyFlags = SignatureSubpacketsUtil.parseKeyFlags(bindingSignature); + if (keyFlags != null) { + return keyFlags; } } } @@ -385,14 +411,14 @@ public class KeyRingInfo { return Collections.emptyList(); } - PGPSignature userIdCertification = getCurrentUserIdCertification(userId); + PGPSignature userIdCertification = getLatestUserIdCertification(userId); if (userIdCertification == null) { - return Collections.emptyList(); + throw new AssertionError("While user-id '" + userId + "' was reported as valid, there appears to be no certification for it."); } - KeyFlags keyFlags = SignatureSubpacketsUtil.getKeyFlags(userIdCertification); + List keyFlags = SignatureSubpacketsUtil.parseKeyFlags(userIdCertification); if (keyFlags != null) { - return KeyFlag.fromBitmask(keyFlags.getFlags()); + return keyFlags; } return Collections.emptyList(); } @@ -428,7 +454,7 @@ public class KeyRingInfo { private PGPSignature getMostRecentSignature() { Set allSignatures = new HashSet<>(); - PGPSignature mostRecentSelfSignature = getCurrentDirectKeySelfSignature(); + PGPSignature mostRecentSelfSignature = getLatestDirectKeySelfSignature(); PGPSignature revocationSelfSignature = getRevocationSelfSignature(); if (mostRecentSelfSignature != null) allSignatures.add(mostRecentSelfSignature); if (revocationSelfSignature != null) allSignatures.add(revocationSelfSignature); @@ -462,12 +488,12 @@ public class KeyRingInfo { */ public Date getPrimaryKeyExpirationDate() { Date lastExpiration = null; - if (getCurrentDirectKeySelfSignature() != null) { - lastExpiration = SignatureUtils.getKeyExpirationDate(getCreationDate(), getCurrentDirectKeySelfSignature()); + if (getLatestDirectKeySelfSignature() != null) { + lastExpiration = SignatureUtils.getKeyExpirationDate(getCreationDate(), getLatestDirectKeySelfSignature()); } for (String userId : getValidUserIds()) { - PGPSignature signature = getCurrentUserIdCertification(userId); + PGPSignature signature = getLatestUserIdCertification(userId); Date expiration = SignatureUtils.getKeyExpirationDate(getCreationDate(), signature); if (expiration != null && (lastExpiration == null || expiration.after(lastExpiration))) { lastExpiration = expiration; @@ -543,8 +569,9 @@ public class KeyRingInfo { return false; } - public PGPPublicKey getEncryptionSubkey(EncryptionStream.Purpose purpose) { + public List getEncryptionSubkeys(EncryptionStream.Purpose purpose) { Iterator subkeys = keys.getPublicKeys(); + List encryptionKeys = new ArrayList<>(); while (subkeys.hasNext()) { PGPPublicKey subKey = subkeys.next(); @@ -560,36 +587,37 @@ public class KeyRingInfo { switch (purpose) { case COMMUNICATIONS: if (keyFlags.contains(KeyFlag.ENCRYPT_COMMS)) { - return subKey; + encryptionKeys.add(subKey); } break; case STORAGE: if (keyFlags.contains(KeyFlag.ENCRYPT_STORAGE)) { - return subKey; + encryptionKeys.add(subKey); } break; case STORAGE_AND_COMMUNICATIONS: if (keyFlags.contains(KeyFlag.ENCRYPT_COMMS) || keyFlags.contains(KeyFlag.ENCRYPT_STORAGE)) { - return subKey; + encryptionKeys.add(subKey); } break; } } - return null; + return encryptionKeys; } - public PGPPublicKey getEncryptionSubkey(String userId, EncryptionStream.Purpose purpose) { + public List getEncryptionSubkeys(String userId, EncryptionStream.Purpose purpose) { if (userId != null) { if (!isUserIdValid(userId)) { - throw new KeyValidationException(userId, getCurrentUserIdCertification(userId), getUserIdRevocation(userId)); + throw new KeyValidationException(userId, getLatestUserIdCertification(userId), getUserIdRevocation(userId)); } } - return getEncryptionSubkey(purpose); + return getEncryptionSubkeys(purpose); } - public PGPPublicKey getSigningSubkey() { + public List getSigningSubkeys() { Iterator subkeys = keys.getPublicKeys(); + List signingKeys = new ArrayList<>(); while (subkeys.hasNext()) { PGPPublicKey subKey = subkeys.next(); @@ -599,16 +627,16 @@ public class KeyRingInfo { List keyFlags = getKeyFlagsOf(subKey.getKeyID()); if (keyFlags.contains(KeyFlag.SIGN_DATA)) { - return subKey; + signingKeys.add(subKey); } } - return null; + return signingKeys; } public List getPreferredHashAlgorithms(String userId, long keyID) { - PGPSignature signature = getCurrentUserIdCertification(userId == null ? getPrimaryUserId() : userId); + PGPSignature signature = getLatestUserIdCertification(userId == null ? getPrimaryUserId() : userId); if (signature == null) { - signature = getCurrentDirectKeySelfSignature(); + signature = getLatestDirectKeySelfSignature(); } if (signature == null) { signature = getCurrentSubkeyBindingSignature(keyID); diff --git a/pgpainless-core/src/test/java/org/pgpainless/weird_keys/TestTwoSubkeysEncryption.java b/pgpainless-core/src/test/java/org/pgpainless/weird_keys/TestTwoSubkeysEncryption.java index 0220f6ec..750d1e23 100644 --- a/pgpainless-core/src/test/java/org/pgpainless/weird_keys/TestTwoSubkeysEncryption.java +++ b/pgpainless-core/src/test/java/org/pgpainless/weird_keys/TestTwoSubkeysEncryption.java @@ -26,11 +26,12 @@ import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPPublicKeyRing; import org.bouncycastle.openpgp.PGPSecretKeyRing; import org.bouncycastle.util.io.Streams; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.pgpainless.PGPainless; +import org.pgpainless.encryption_signing.EncryptionOptions; import org.pgpainless.encryption_signing.EncryptionResult; import org.pgpainless.encryption_signing.EncryptionStream; +import org.pgpainless.encryption_signing.ProducerOptions; import org.pgpainless.key.WeirdKeys; import org.pgpainless.key.util.KeyRingUtils; @@ -46,23 +47,25 @@ public class TestTwoSubkeysEncryption { * {@link WeirdKeys#TWO_CRYPT_SUBKEYS} is a key that has two subkeys which both carry the key flags * {@link org.pgpainless.algorithm.KeyFlag#ENCRYPT_COMMS} and {@link org.pgpainless.algorithm.KeyFlag#ENCRYPT_STORAGE}. * - * This test makes sure that both subkeys are used for encryption. + * This test verifies that {@link EncryptionOptions#addRecipient(PGPPublicKeyRing, EncryptionOptions.EncryptionKeySelector)} + * works properly, if {@link EncryptionOptions#encryptToAllCapableSubkeys()} is provided as argument. * * @throws IOException not expected * @throws PGPException not expected */ @Test - @Disabled("We may not want to encrypt to all enc capable subkeys.") public void testEncryptsToBothSubkeys() throws IOException, PGPException { PGPSecretKeyRing twoSuitableSubkeysKeyRing = WeirdKeys.getTwoCryptSubkeysKey(); PGPPublicKeyRing publicKeys = KeyRingUtils.publicKeyRingFrom(twoSuitableSubkeysKeyRing); ByteArrayOutputStream out = new ByteArrayOutputStream(); EncryptionStream encryptionStream = PGPainless.encryptAndOrSign(EncryptionStream.Purpose.STORAGE) .onOutputStream(out) - .toRecipient(publicKeys) - .and() - .doNotSign() - .noArmor(); + .withOptions( + ProducerOptions.encrypt(new EncryptionOptions(EncryptionStream.Purpose.STORAGE_AND_COMMUNICATIONS) + .addRecipient(publicKeys, EncryptionOptions.encryptToAllCapableSubkeys()) + ) + .setAsciiArmor(false) + ); Streams.pipeAll(getPlainIn(), encryptionStream); encryptionStream.close();