diff --git a/pgpainless-core/src/main/java/org/pgpainless/PGPainless.java b/pgpainless-core/src/main/java/org/pgpainless/PGPainless.java index 4cfbf92c..5c7545da 100644 --- a/pgpainless-core/src/main/java/org/pgpainless/PGPainless.java +++ b/pgpainless-core/src/main/java/org/pgpainless/PGPainless.java @@ -15,15 +15,9 @@ */ package org.pgpainless; -import java.io.IOException; -import javax.annotation.Nonnull; - -import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPKeyRing; import org.bouncycastle.openpgp.PGPSecretKeyRing; -import org.pgpainless.algorithm.CompressionAlgorithm; import org.pgpainless.algorithm.EncryptionPurpose; -import org.pgpainless.algorithm.SymmetricKeyAlgorithm; import org.pgpainless.decryption_verification.DecryptionBuilder; import org.pgpainless.decryption_verification.DecryptionStream; import org.pgpainless.encryption_signing.EncryptionBuilder; @@ -36,8 +30,6 @@ import org.pgpainless.key.parsing.KeyRingReader; import org.pgpainless.policy.Policy; import org.pgpainless.signature.cleartext_signatures.VerifyCleartextSignatures; import org.pgpainless.signature.cleartext_signatures.VerifyCleartextSignaturesImpl; -import org.pgpainless.symmetric_encryption.SymmetricEncryptorDecryptor; -import org.pgpainless.util.Passphrase; public class PGPainless { @@ -135,43 +127,6 @@ public class PGPainless { return new KeyRingInfo(keyRing); } - /** - * Encrypt some data symmetrically using OpenPGP and a password. - * The resulting data will be uncompressed and integrity protected. - * - * @param data input data. - * @param password password. - * @param algorithm symmetric encryption algorithm. - * @return symmetrically OpenPGP encrypted data. - * - * @throws IOException IO is dangerous. - * @throws PGPException PGP is brittle. - * @deprecated use {@link #encryptAndOrSign()} instead and provide a passphrase in - * {@link org.pgpainless.encryption_signing.EncryptionOptions#addPassphrase(Passphrase)}. - */ - @Deprecated - public static byte[] encryptWithPassword(@Nonnull byte[] data, @Nonnull Passphrase password, @Nonnull SymmetricKeyAlgorithm algorithm) throws IOException, PGPException { - return SymmetricEncryptorDecryptor.symmetricallyEncrypt(data, password, - algorithm, CompressionAlgorithm.UNCOMPRESSED); - } - - /** - * Decrypt some symmetrically encrypted data using a password. - * The data is suspected to be integrity protected. - * - * @param data symmetrically OpenPGP encrypted data. - * @param password password. - * @return decrypted data. - * @throws IOException IO is dangerous. - * @throws PGPException PGP is brittle. - * @deprecated Use {@link #decryptAndOrVerify()} instead and provide the decryption passphrase in - * {@link org.pgpainless.decryption_verification.DecryptionBuilder.DecryptWith#decryptWith(Passphrase)}. - */ - @Deprecated - public static byte[] decryptWithPassword(@Nonnull byte[] data, @Nonnull Passphrase password) throws IOException, PGPException { - return SymmetricEncryptorDecryptor.symmetricallyDecrypt(data, password); - } - public static Policy getPolicy() { return Policy.getInstance(); } diff --git a/pgpainless-core/src/main/java/org/pgpainless/symmetric_encryption/SymmetricEncryptorDecryptor.java b/pgpainless-core/src/main/java/org/pgpainless/symmetric_encryption/SymmetricEncryptorDecryptor.java deleted file mode 100644 index bfbc0024..00000000 --- a/pgpainless-core/src/main/java/org/pgpainless/symmetric_encryption/SymmetricEncryptorDecryptor.java +++ /dev/null @@ -1,193 +0,0 @@ -/* - * Copyright 2018 Paul Schaub. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.pgpainless.symmetric_encryption; - -import javax.annotation.Nonnull; -import java.io.BufferedInputStream; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.security.SecureRandom; -import java.util.Date; - -import org.bouncycastle.openpgp.PGPCompressedData; -import org.bouncycastle.openpgp.PGPCompressedDataGenerator; -import org.bouncycastle.openpgp.PGPEncryptedDataGenerator; -import org.bouncycastle.openpgp.PGPEncryptedDataList; -import org.bouncycastle.openpgp.PGPException; -import org.bouncycastle.openpgp.PGPLiteralData; -import org.bouncycastle.openpgp.PGPLiteralDataGenerator; -import org.bouncycastle.openpgp.PGPPBEEncryptedData; -import org.bouncycastle.openpgp.PGPUtil; -import org.bouncycastle.openpgp.bc.BcPGPObjectFactory; -import org.bouncycastle.openpgp.operator.bc.BcPBEDataDecryptorFactory; -import org.bouncycastle.openpgp.operator.bc.BcPGPDigestCalculatorProvider; -import org.bouncycastle.openpgp.operator.jcajce.JcePBEKeyEncryptionMethodGenerator; -import org.bouncycastle.openpgp.operator.jcajce.JcePGPDataEncryptorBuilder; -import org.bouncycastle.util.io.Streams; -import org.pgpainless.algorithm.CompressionAlgorithm; -import org.pgpainless.algorithm.SymmetricKeyAlgorithm; -import org.pgpainless.provider.ProviderFactory; -import org.pgpainless.util.Passphrase; - -/** - * Stolen from - * Bouncycastle examples. - */ -public class SymmetricEncryptorDecryptor { - - /** - * Encrypt some {@code data} symmetrically using an {@code encryptionAlgorithm} and a given {@code password}. - * The input data will be compressed using the given {@code compressionAlgorithm} and packed in a modification - * detection package, which is then encrypted. - * - * @param data bytes that will be encrypted - * @param password password that will be used to encrypt the data - * @param encryptionAlgorithm symmetric algorithm that will be used to encrypt the data - * @param compressionAlgorithm compression algorithm that will be used to compress the data - * @return encrypted data - * @throws IOException IO is dangerous - * @throws PGPException OpenPGP is brittle - */ - public static byte[] symmetricallyEncrypt(@Nonnull byte[] data, - @Nonnull Passphrase password, - @Nonnull SymmetricKeyAlgorithm encryptionAlgorithm, - @Nonnull CompressionAlgorithm compressionAlgorithm) - throws IOException, PGPException { - - byte[] compressedData = compress(data, compressionAlgorithm.getAlgorithmId()); - - ByteArrayOutputStream bOut = new ByteArrayOutputStream(); - - PGPEncryptedDataGenerator encGen = new PGPEncryptedDataGenerator( - new JcePGPDataEncryptorBuilder(encryptionAlgorithm.getAlgorithmId()) - .setWithIntegrityPacket(true) - .setSecureRandom(new SecureRandom()) - .setProvider(ProviderFactory.getProvider())); - - encGen.addMethod(new JcePBEKeyEncryptionMethodGenerator(password.getChars()).setProvider(ProviderFactory.getProvider())); - - OutputStream encOut = encGen.open(bOut, compressedData.length); - - encOut.write(compressedData); - encOut.close(); - - return bOut.toByteArray(); - } - - /** - * Decrypt and decompress some symmetrically encrypted data using a password. - * Note, that decryption will fail if the given data is not integrity protected with a modification detection - * package. - * - * @param data encrypted data - * @param password password to decrypt the data - * @return decrypted data - * @throws IOException IO is dangerous - * @throws PGPException OpenPGP is brittle - */ - public static byte[] symmetricallyDecrypt(@Nonnull byte[] data, @Nonnull Passphrase password) - throws IOException, PGPException { - PGPPBEEncryptedData pbe; - ByteArrayOutputStream outputStream = null; - BufferedInputStream bis = new BufferedInputStream(new ByteArrayInputStream(data)); - InputStream in = PGPUtil.getDecoderStream(bis); - - try { - BcPGPObjectFactory pgpF = new BcPGPObjectFactory(in); - PGPEncryptedDataList enc; - Object o = pgpF.nextObject(); - - if (o instanceof PGPEncryptedDataList) { - enc = (PGPEncryptedDataList) o; - } else { - enc = (PGPEncryptedDataList) pgpF.nextObject(); - } - - pbe = (PGPPBEEncryptedData) enc.get(0); - - InputStream clear = pbe.getDataStream( - new BcPBEDataDecryptorFactory(password.getChars(), new BcPGPDigestCalculatorProvider())); - - BcPGPObjectFactory pgpFact = new BcPGPObjectFactory(clear); - - o = pgpFact.nextObject(); - if (o instanceof PGPCompressedData) { - PGPCompressedData cData = (PGPCompressedData) o; - pgpFact = new BcPGPObjectFactory(cData.getDataStream()); - o = pgpFact.nextObject(); - } - - PGPLiteralData ld = (PGPLiteralData) o; - InputStream unc = ld.getInputStream(); - - try { - outputStream = new ByteArrayOutputStream(); - - Streams.pipeAll(unc, outputStream); - } finally { - if (outputStream != null) { - outputStream.close(); - } - } - } finally { - in.close(); - } - - if (pbe.isIntegrityProtected()) { - if (!pbe.verify()) { - throw new PGPException("Integrity check failed."); - } - } else { - throw new PGPException("Symmetrically encrypted data is not integrity protected."); - } - - return outputStream.toByteArray(); - } - - /** - * Wrap some data in an OpenPGP compressed data package. - * - * @param clearData uncompressed data - * @param algorithm compression algorithm - * @return compressed data - * @throws IOException IO is dangerous - */ - private static byte[] compress(@Nonnull byte[] clearData, int algorithm) throws IOException { - ByteArrayOutputStream bOut = new ByteArrayOutputStream(); - PGPCompressedDataGenerator comData = new PGPCompressedDataGenerator(algorithm); - OutputStream cos = comData.open(bOut); - - PGPLiteralDataGenerator lData = new PGPLiteralDataGenerator(); - - OutputStream pOut = lData.open(cos, - PGPLiteralData.BINARY, - PGPLiteralDataGenerator.CONSOLE, - clearData.length, - new Date() - ); - - pOut.write(clearData); - pOut.close(); - - comData.close(); - - return bOut.toByteArray(); - } - -} diff --git a/pgpainless-core/src/main/java/org/pgpainless/symmetric_encryption/package-info.java b/pgpainless-core/src/main/java/org/pgpainless/symmetric_encryption/package-info.java deleted file mode 100644 index a250b706..00000000 --- a/pgpainless-core/src/main/java/org/pgpainless/symmetric_encryption/package-info.java +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright 2018 Paul Schaub. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * Classes related to OpenPGP symmetric encryption. - */ -package org.pgpainless.symmetric_encryption; diff --git a/pgpainless-core/src/test/java/org/pgpainless/symmetric_encryption/LegacySymmetricEncryptionTest.java b/pgpainless-core/src/test/java/org/pgpainless/symmetric_encryption/LegacySymmetricEncryptionTest.java deleted file mode 100644 index 477e0067..00000000 --- a/pgpainless-core/src/test/java/org/pgpainless/symmetric_encryption/LegacySymmetricEncryptionTest.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright 2018 Paul Schaub. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.pgpainless.symmetric_encryption; - -import static org.junit.jupiter.api.Assertions.assertArrayEquals; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.util.logging.Level; -import java.util.logging.Logger; - -import org.bouncycastle.bcpg.ArmoredOutputStream; -import org.bouncycastle.openpgp.PGPException; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.MethodSource; -import org.pgpainless.PGPainless; -import org.pgpainless.algorithm.SymmetricKeyAlgorithm; -import org.pgpainless.implementation.ImplementationFactory; -import org.pgpainless.util.ArmoredOutputStreamFactory; -import org.pgpainless.util.Passphrase; - -public class LegacySymmetricEncryptionTest { - - private static final Logger LOGGER = Logger.getLogger(LegacySymmetricEncryptionTest.class.getName()); - - private static final String message = - "I grew up with the understanding that the world " + - "I lived in was one where people enjoyed a sort of freedom " + - "to communicate with each other in privacy, without it " + - "being monitored, without it being measured or analyzed " + - "or sort of judged by these shadowy figures or systems, " + - "any time they mention anything that travels across " + - "public lines.\n" + - "\n" + - "- Edward Snowden -"; - - @SuppressWarnings("deprecation") - @ParameterizedTest - @MethodSource("org.pgpainless.util.TestUtil#provideImplementationFactories") - public void testSymmetricEncryptionDecryption(ImplementationFactory implementationFactory) throws IOException, PGPException { - ImplementationFactory.setFactoryImplementation(implementationFactory); - byte[] plain = message.getBytes(); - String password = "choose_a_better_password_please"; - Passphrase passphrase = new Passphrase(password.toCharArray()); - byte[] enc = PGPainless.encryptWithPassword(plain, passphrase, SymmetricKeyAlgorithm.AES_128); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - ArmoredOutputStream armor = ArmoredOutputStreamFactory.get(out); - armor.write(enc); - armor.flush(); - armor.close(); - - // Print cipher text for validation with GnuPG. - LOGGER.log(Level.INFO, String.format("Use ciphertext below for manual validation with GnuPG " + - "(passphrase = '%s').\n\n%s", password, new String(out.toByteArray()))); - - byte[] plain2 = PGPainless.decryptWithPassword(enc, passphrase); - assertArrayEquals(plain, plain2); - } -}