Example usage for org.bouncycastle.openpgp.operator.bc BcPublicKeyDataDecryptorFactory BcPublicKeyDataDecryptorFactory

List of usage examples for org.bouncycastle.openpgp.operator.bc BcPublicKeyDataDecryptorFactory BcPublicKeyDataDecryptorFactory

Introduction

In this page you can find the example usage for org.bouncycastle.openpgp.operator.bc BcPublicKeyDataDecryptorFactory BcPublicKeyDataDecryptorFactory.

Prototype

public BcPublicKeyDataDecryptorFactory(PGPPrivateKey privKey) 

Source Link

Usage

From source file:alpha.offsync.security.OpenPGPSecurityUtility.java

License:Apache License

@Override
public void decrypt(final OutputStream outputStream, final InputStream inputStream) {

    try {/*w  ww. j ava  2s.  c  o  m*/
        final File keyFile = this.secretKeyRing;
        final char[] passwd = this.secretKeyRingPassword;

        final InputStream in = PGPUtil.getDecoderStream(inputStream);

        try {
            final PGPObjectFactory pgpF = new PGPObjectFactory(in);
            PGPEncryptedDataList enc;

            final Object o = pgpF.nextObject();

            if (o instanceof PGPEncryptedDataList) {
                enc = (PGPEncryptedDataList) o;
            } else {
                enc = (PGPEncryptedDataList) pgpF.nextObject();
            }

            final Iterator it = enc.getEncryptedDataObjects();
            PGPPrivateKey sKey = null;
            PGPPublicKeyEncryptedData pbe = null;
            final PGPSecretKeyRingCollection pgpSec = new PGPSecretKeyRingCollection(
                    PGPUtil.getDecoderStream(new FileInputStream(keyFile)));

            while ((sKey == null) && it.hasNext()) {
                pbe = (PGPPublicKeyEncryptedData) it.next();

                sKey = this.findSecretKey(pgpSec, pbe.getKeyID(), passwd);
            }

            if (sKey == null)
                throw new IllegalArgumentException("secret key for message not found.");

            final InputStream clear = pbe.getDataStream(new BcPublicKeyDataDecryptorFactory(sKey));

            final PGPObjectFactory plainFact = new PGPObjectFactory(clear);

            final PGPCompressedData cData = (PGPCompressedData) plainFact.nextObject();

            final InputStream compressedStream = new BufferedInputStream(cData.getDataStream());
            final PGPObjectFactory pgpFact = new PGPObjectFactory(compressedStream);

            final Object message = pgpFact.nextObject();

            if (message instanceof PGPLiteralData) {
                final PGPLiteralData ld = (PGPLiteralData) message;

                final InputStream unc = ld.getInputStream();
                final OutputStream fOut = new BufferedOutputStream(outputStream);

                Streams.pipeAll(unc, fOut);

                fOut.close();
            } else if (message instanceof PGPOnePassSignatureList)
                throw new PGPException("encrypted message contains a signed message - not literal data.");
            else
                throw new PGPException("message is not a simple encrypted file - type unknown.");
        } catch (final PGPException e) {
            System.err.println(e);
            if (e.getUnderlyingException() != null) {
                e.getUnderlyingException().printStackTrace();
            }
        }
    } catch (final FileNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (final IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

From source file:com.google.e2e.bcdriver.Decryptor.java

License:Apache License

private static final Result decryptSignedContent(PGPPublicKeyEncryptedData pked, PGPPrivateKey decryptKey,
        KeyChecker.PKR verify) throws IOException, PGPException, SignatureException {

    InputStream clear = pked.getDataStream(new BcPublicKeyDataDecryptorFactory(decryptKey));

    Result ret = verifySignedContent(clear, verify);
    // Also check the message integrity
    if (pked.isIntegrityProtected() && !pked.verify()) {
        throw new IOException("Integrity check failed");
    }/*w  w  w  .  j  av  a2  s. com*/
    return ret;
}

From source file:google.registry.rde.BouncyCastleTest.java

License:Open Source License

@Test
public void testEncryptDecrypt_ExplicitStyle() throws Exception {
    int bufferSize = 64 * 1024;

    // Alice loads Bob's "publicKey" into memory.
    PGPPublicKeyRing publicKeyRing = new BcPGPPublicKeyRing(PUBLIC_KEY);
    PGPPublicKey publicKey = publicKeyRing.getPublicKey();

    // Alice encrypts the secret message for Bob using his "publicKey".
    PGPEncryptedDataGenerator encryptor = new PGPEncryptedDataGenerator(new BcPGPDataEncryptorBuilder(AES_128));
    encryptor.addMethod(new BcPublicKeyKeyEncryptionMethodGenerator(publicKey));
    byte[] encryptedData;
    try (ByteArrayOutputStream output = new ByteArrayOutputStream()) {
        try (OutputStream output2 = encryptor.open(output, new byte[bufferSize])) {
            output2.write(FALL_OF_HYPERION_A_DREAM.getBytes(UTF_8));
        }//from   w  w w.  j a  va  2  s  .c om
        encryptedData = output.toByteArray();
    }
    logger.info("Encrypted data: " + dumpHex(encryptedData));

    // Bob loads his "privateKey" into memory.
    PGPSecretKeyRing privateKeyRing = new BcPGPSecretKeyRing(PRIVATE_KEY);
    PGPPrivateKey privateKey = extractPrivateKey(privateKeyRing.getSecretKey());

    // Bob decrypt's the OpenPGP message (w/ ciphertext) using his "privateKey".
    try (ByteArrayInputStream input = new ByteArrayInputStream(encryptedData)) {
        PGPObjectFactory pgpFact = new BcPGPObjectFactory(input);
        PGPEncryptedDataList encDataList = (PGPEncryptedDataList) pgpFact.nextObject();
        assertThat(encDataList.size()).isEqualTo(1);
        PGPPublicKeyEncryptedData encData = (PGPPublicKeyEncryptedData) encDataList.get(0);
        assertThat(encData.getKeyID()).isEqualTo(publicKey.getKeyID());
        assertThat(encData.getKeyID()).isEqualTo(privateKey.getKeyID());
        try (InputStream original = encData.getDataStream(new BcPublicKeyDataDecryptorFactory(privateKey))) {
            assertThat(CharStreams.toString(new InputStreamReader(original, UTF_8)))
                    .isEqualTo(FALL_OF_HYPERION_A_DREAM);
        }
    }
}

From source file:google.registry.rde.BouncyCastleTest.java

License:Open Source License

@Test
public void testEncryptDecrypt_KeyRingStyle() throws Exception {
    int bufferSize = 64 * 1024;

    // Alice loads Bob's "publicKey" into memory from her public key ring.
    PGPPublicKeyRingCollection publicKeyRings = new BcPGPPublicKeyRingCollection(
            PGPUtil.getDecoderStream(new ByteArrayInputStream(PUBLIC_KEY)));
    PGPPublicKeyRing publicKeyRing = publicKeyRings.getKeyRings("eric@bouncycastle.org", true, true).next();
    PGPPublicKey publicKey = publicKeyRing.getPublicKey();

    // Alice encrypts the secret message for Bob using his "publicKey".
    PGPEncryptedDataGenerator encryptor = new PGPEncryptedDataGenerator(new BcPGPDataEncryptorBuilder(AES_128));
    encryptor.addMethod(new BcPublicKeyKeyEncryptionMethodGenerator(publicKey));
    byte[] encryptedData;
    try (ByteArrayOutputStream output = new ByteArrayOutputStream()) {
        try (OutputStream output2 = encryptor.open(output, new byte[bufferSize])) {
            output2.write(FALL_OF_HYPERION_A_DREAM.getBytes(UTF_8));
        }//from   w w  w  .ja v a 2  s.c o  m
        encryptedData = output.toByteArray();
    }
    logger.info("Encrypted data: " + dumpHex(encryptedData));

    // Bob loads his chain of private keys into memory.
    PGPSecretKeyRingCollection privateKeyRings = new BcPGPSecretKeyRingCollection(
            PGPUtil.getDecoderStream(new ByteArrayInputStream(PRIVATE_KEY)));

    // Bob decrypt's the OpenPGP message (w/ ciphertext) using his "privateKey".
    try (ByteArrayInputStream input = new ByteArrayInputStream(encryptedData)) {
        PGPObjectFactory pgpFact = new BcPGPObjectFactory(input);
        PGPEncryptedDataList encDataList = (PGPEncryptedDataList) pgpFact.nextObject();
        assertThat(encDataList.size()).isEqualTo(1);
        PGPPublicKeyEncryptedData encData = (PGPPublicKeyEncryptedData) encDataList.get(0);
        // Bob loads the private key to which the message is addressed.
        PGPPrivateKey privateKey = extractPrivateKey(privateKeyRings.getSecretKey(encData.getKeyID()));
        try (InputStream original = encData.getDataStream(new BcPublicKeyDataDecryptorFactory(privateKey))) {
            assertThat(CharStreams.toString(new InputStreamReader(original, UTF_8)))
                    .isEqualTo(FALL_OF_HYPERION_A_DREAM);
        }
    }
}

From source file:google.registry.rde.BouncyCastleTest.java

License:Open Source License

@Test
public void testCompressEncryptDecryptDecompress_KeyRingStyle() throws Exception {
    int bufsz = 64 * 1024;

    // Alice loads Bob's "publicKey" into memory from her public key ring.
    PGPPublicKeyRingCollection publicKeyRings = new BcPGPPublicKeyRingCollection(
            PGPUtil.getDecoderStream(new ByteArrayInputStream(PUBLIC_KEY)));
    PGPPublicKeyRing publicKeyRing = publicKeyRings.getKeyRings("eric@bouncycastle.org", true, true).next();
    PGPPublicKey publicKey = publicKeyRing.getPublicKey();

    // Alice encrypts the secret message for Bob using his "publicKey".
    PGPEncryptedDataGenerator encryptor = new PGPEncryptedDataGenerator(new BcPGPDataEncryptorBuilder(AES_128));
    encryptor.addMethod(new BcPublicKeyKeyEncryptionMethodGenerator(publicKey));
    byte[] encryptedData;
    try (ByteArrayOutputStream output = new ByteArrayOutputStream()) {
        try (OutputStream output2 = encryptor.open(output, new byte[bufsz])) {
            PGPCompressedDataGenerator kompressor = new PGPCompressedDataGenerator(ZIP);
            try (OutputStream output3 = kompressor.open(output2, new byte[bufsz])) {
                output3.write(FALL_OF_HYPERION_A_DREAM.getBytes(UTF_8));
            }//  www  .ja va2s. c  o m
        }
        encryptedData = output.toByteArray();
    }
    logger.info("Encrypted data: " + dumpHex(encryptedData));

    // Bob loads his chain of private keys into memory.
    PGPSecretKeyRingCollection privateKeyRings = new BcPGPSecretKeyRingCollection(
            PGPUtil.getDecoderStream(new ByteArrayInputStream(PRIVATE_KEY)));

    // Bob decrypt's the OpenPGP message (w/ ciphertext) using his "privateKey".
    try (ByteArrayInputStream input = new ByteArrayInputStream(encryptedData)) {
        PGPObjectFactory pgpFact = new BcPGPObjectFactory(input);
        PGPEncryptedDataList encDataList = (PGPEncryptedDataList) pgpFact.nextObject();
        assertThat(encDataList.size()).isEqualTo(1);
        PGPPublicKeyEncryptedData encData = (PGPPublicKeyEncryptedData) encDataList.get(0);
        // Bob loads the private key to which the message is addressed.
        PGPPrivateKey privateKey = extractPrivateKey(privateKeyRings.getSecretKey(encData.getKeyID()));
        try (InputStream original = encData.getDataStream(new BcPublicKeyDataDecryptorFactory(privateKey))) {
            pgpFact = new BcPGPObjectFactory(original);
            PGPCompressedData kompressedData = (PGPCompressedData) pgpFact.nextObject();
            try (InputStream orig2 = kompressedData.getDataStream()) {
                assertThat(CharStreams.toString(new InputStreamReader(orig2, UTF_8)))
                        .isEqualTo(FALL_OF_HYPERION_A_DREAM);
            }
        }
    }
}

From source file:google.registry.rde.Ghostryde.java

License:Open Source License

/**
 * Opens a new {@link Decryptor} (Reading Step 1/3)
 *
 * <p>This is the first step in opening a ghostryde file. After this method, you'll want to
 * call {@link #openDecompressor(Decryptor)}.
 *
 * @param input is an {@link InputStream} of the ghostryde file data.
 * @param privateKey is the private encryption key of the recipient (which is us!)
 * @throws IOException//  w  ww.  ja v  a 2 s  .  co m
 * @throws PGPException
 */
@CheckReturnValue
public Decryptor openDecryptor(@WillNotClose InputStream input, PGPPrivateKey privateKey)
        throws IOException, PGPException {
    checkNotNull(privateKey, "privateKey");
    PGPObjectFactory fact = new BcPGPObjectFactory(checkNotNull(input, "input"));
    PGPEncryptedDataList crypts = pgpCast(fact.nextObject(), PGPEncryptedDataList.class);
    checkState(crypts.size() > 0);
    if (crypts.size() > 1) {
        logger.warningfmt("crypts.size() is %d (should be 1)", crypts.size());
    }
    PGPPublicKeyEncryptedData crypt = pgpCast(crypts.get(0), PGPPublicKeyEncryptedData.class);
    if (crypt.getKeyID() != privateKey.getKeyID()) {
        throw new PGPException(String.format("Message was encrypted for keyid %x but ours is %x",
                crypt.getKeyID(), privateKey.getKeyID()));
    }
    return new Decryptor(crypt.getDataStream(new BcPublicKeyDataDecryptorFactory(privateKey)), crypt);
}

From source file:org.kontalk.crypto.Coder.java

License:Open Source License

private static DecryptionResult decryptAndVerify(InputStream encryptedStream, PersonalKey myKey,
        PGPPublicKey senderKey) {// w  ww  .j  av a 2 s.c o m
    // note: the signature is inside the encrypted data

    DecryptionResult result = new DecryptionResult();

    PGPObjectFactory pgpFactory = new PGPObjectFactory(encryptedStream);

    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();

    try { // catch all IO and PGP exceptions

        // the first object might be a PGP marker packet
        Object o = pgpFactory.nextObject(); // nullable
        if (!(o instanceof PGPEncryptedDataList)) {
            o = pgpFactory.nextObject(); // nullable
        }

        if (!(o instanceof PGPEncryptedDataList)) {
            LOGGER.warning("can't find encrypted data list in data");
            result.errors.add(Error.INVALID_DATA);
            return result;
        }
        PGPEncryptedDataList encDataList = (PGPEncryptedDataList) o;

        // check if secret key matches our encryption keyID
        Iterator<?> it = encDataList.getEncryptedDataObjects();
        PGPPrivateKey sKey = null;
        PGPPublicKeyEncryptedData pbe = null;
        long myKeyID = myKey.getPrivateEncryptionKey().getKeyID();
        while (sKey == null && it.hasNext()) {
            Object i = it.next();
            if (!(i instanceof PGPPublicKeyEncryptedData))
                continue;
            pbe = (PGPPublicKeyEncryptedData) i;
            if (pbe.getKeyID() == myKeyID)
                sKey = myKey.getPrivateEncryptionKey();
        }
        if (sKey == null || pbe == null) {
            LOGGER.warning("private key for message not found");
            result.errors.add(Error.INVALID_PRIVATE_KEY);
            return result;
        }

        InputStream clear = pbe.getDataStream(new BcPublicKeyDataDecryptorFactory(sKey));

        PGPObjectFactory plainFactory = new PGPObjectFactory(clear);

        Object object = plainFactory.nextObject(); // nullable

        if (!(object instanceof PGPCompressedData)) {
            LOGGER.warning("data packet not compressed");
            result.errors.add(Error.INVALID_DATA);
            return result;
        }

        PGPCompressedData cData = (PGPCompressedData) object;
        PGPObjectFactory pgpFact = new PGPObjectFactory(cData.getDataStream());

        object = pgpFact.nextObject(); // nullable

        // the first object could be the signature list
        // get signature from it
        PGPOnePassSignature ops = null;
        if (object instanceof PGPOnePassSignatureList) {
            PGPOnePassSignatureList signatureList = (PGPOnePassSignatureList) object;
            // there is a signature list, so we assume the message is signed
            // (makes sense)
            result.signing = Signing.SIGNED;

            if (signatureList.isEmpty()) {
                LOGGER.warning("signature list is empty");
                result.errors.add(Error.INVALID_SIGNATURE_DATA);
            } else {
                ops = signatureList.get(0);
                ops.init(new BcPGPContentVerifierBuilderProvider(), senderKey);
            }
            object = pgpFact.nextObject(); // nullable
        } else {
            LOGGER.warning("signature list not found");
            result.signing = Signing.NOT;
        }

        if (!(object instanceof PGPLiteralData)) {
            LOGGER.warning("unknown packet type: " + object.getClass().getName());
            result.errors.add(Error.INVALID_DATA);
            return result;
        }

        PGPLiteralData ld = (PGPLiteralData) object;
        InputStream unc = ld.getInputStream();
        int ch;
        while ((ch = unc.read()) >= 0) {
            outputStream.write(ch);
            if (ops != null)
                try {
                    ops.update((byte) ch);
                } catch (SignatureException ex) {
                    LOGGER.log(Level.WARNING, "can't read signature", ex);
                }
        }

        result.decryptedStream = Optional.of(outputStream);

        if (ops != null) {
            result = verifySignature(result, pgpFact, ops);
        }

        // verify message integrity
        if (pbe.isIntegrityProtected()) {
            if (!pbe.verify()) {
                LOGGER.warning("message integrity check failed");
                result.errors.add(Error.INVALID_INTEGRITY);
            }
        } else {
            LOGGER.warning("message is not integrity protected");
            result.errors.add(Error.NO_INTEGRITY);
        }

    } catch (IOException | PGPException ex) {
        LOGGER.log(Level.WARNING, "can't decrypt message", ex);
        result.errors.add(Error.UNKNOWN_ERROR);
    }

    return result;
}

From source file:org.pgptool.gui.encryption.implpgp.EncryptionServicePgpImpl.java

License:Open Source License

/**
 * decrypt the passed in message stream.
 * //  w  ww.j  a  v  a  2s.  co m
 * Inspired by
 * https://github.com/bcgit/bc-java/blob/master/pg/src/main/java/org/bouncycastle/openpgp/examples/KeyBasedFileProcessor.java
 * 
 * @param countingStream
 *            this stream is passed for progress reporting only, must not be
 *            used to actually read data
 */
private void decryptStream(PGPPublicKeyEncryptedData pbe, PGPPrivateKey privateKey, OutputStream outputStream,
        Updater optionalProgress, CountingInputStream countingStream)
        throws UserRequestedCancellationException {
    try {
        InputStream clear = pbe.getDataStream(new BcPublicKeyDataDecryptorFactory(privateKey));

        BcPGPObjectFactory plainFact = new BcPGPObjectFactory(clear);
        Object message = plainFact.nextObject();
        if (message instanceof PGPMarker) {
            message = plainFact.nextObject();
        }

        BcPGPObjectFactory pgpFactory = null;
        if (message instanceof PGPCompressedData) {
            PGPCompressedData cData = (PGPCompressedData) message;
            pgpFactory = new BcPGPObjectFactory(cData.getDataStream());
            message = pgpFactory.nextObject();
        }

        int watchDog = 0;
        while (message != null) {
            Preconditions.checkState(watchDog++ < 100, "Inifinite loop watch dog just hit");

            if (message instanceof PGPLiteralData) {
                PGPLiteralData ld = (PGPLiteralData) message;

                // NOTE: We know initial file name (in case we need it):
                // ld.getFileName();
                InputStream unc = ld.getInputStream();
                OutputStream fOut = new BufferedOutputStream(outputStream);
                if (optionalProgress != null) {
                    optionalProgress.updateStepInfo("progress.decrypting");
                }

                pipeStream(unc, fOut, BUFFER_SIZE, optionalProgress, countingStream);
                fOut.close();
                unc.close();

                if (pbe.isIntegrityProtected()) {
                    if (!pbe.verify()) {
                        throw new RuntimeException("message failed integrity check");
                    }
                }
                return;
            } else if (message instanceof PGPOnePassSignatureList) {
                log.info("PGPOnePassSignatureList is not implemented yet. Skipping signature validation");
                // NOTE: Here is a place to copyright from
                // http://stackoverflow.com/questions/19173181/bouncycastle-pgp-decrypt-and-verify
                Preconditions.checkArgument(pgpFactory != null,
                        "File format is not supported. pgpFact is supposed to be initialized by that time");
                message = pgpFactory.nextObject();
            } else if (message instanceof PGPSignatureList) {
                log.info("PGPSignatureList is not implemented yet. Skipping signature validation");
                Preconditions.checkArgument(pgpFactory != null,
                        "File format is not supported. pgpFact is supposed to be initialized by that time");
                message = pgpFactory.nextObject();
            } else {
                throw new PGPException(
                        "Don't know how to decrypt the input file. Encountered unexpected block: " + message);
            }
        }
    } catch (Throwable e) {
        Throwables.throwIfInstanceOf(e, UserRequestedCancellationException.class);
        throw new RuntimeException("Decryption failed", e);
    }
}

From source file:org.pgptool.gui.encryption.implpgp.EncryptionServicePgpImpl.java

License:Open Source License

private String getInitialFileName(PGPPublicKeyEncryptedData pbe, PGPPrivateKey privateKey) {
    InputStream clear = null;/*  w  ww .j  a v  a 2 s  . c o m*/
    try {
        clear = pbe.getDataStream(new BcPublicKeyDataDecryptorFactory(privateKey));

        BcPGPObjectFactory plainFact = new BcPGPObjectFactory(clear);
        Object message = plainFact.nextObject();
        if (message instanceof PGPMarker) {
            message = plainFact.nextObject();
        }

        BcPGPObjectFactory pgpFactory = null;
        if (message instanceof PGPCompressedData) {
            PGPCompressedData cData = (PGPCompressedData) message;
            pgpFactory = new BcPGPObjectFactory(cData.getDataStream());
            message = pgpFactory.nextObject();
        }

        int watchDog = 0;
        while (message != null) {
            Preconditions.checkState(watchDog++ < 100, "Inifinite loop watch dog just hit");
            if (message instanceof PGPLiteralData) {
                PGPLiteralData ld = (PGPLiteralData) message;
                return ld.getFileName();
            } else if (message instanceof PGPOnePassSignatureList) {
                Preconditions.checkState(pgpFactory != null, "pgpFactory supposed to be not null");
                message = pgpFactory.nextObject();
            } else if (message instanceof PGPSignatureList) {
                Preconditions.checkState(pgpFactory != null, "pgpFactory supposed to be not null");
                message = pgpFactory.nextObject();
            } else {
                throw new PGPException(
                        "Don't know how to decrypt the input file. Encountered unexpected block: " + message);
            }
        }
        throw new IllegalStateException("Unknown file format, cannot determine initial file name");
    } catch (Throwable e) {
        throw new RuntimeException("Failed to get initial file name", e);
    } finally {
        IoStreamUtils.safeClose(clear);
    }
}

From source file:uk.co.platosys.dinigma.CryptoEngine.java

License:GNU General Public License

/**
 *  Decrypts an InputStream to a Document
 *
 * @param inputStream/*from w w w. j  a v  a2s.co m*/
 * @param key
 * @param passphrase
 * @return
 * @throws Exception
 */

public static String decrypt(InputStream inputStream, Key key, char[] passphrase)
        throws MinigmaException, DecryptionException, java.io.IOException {
    InputStream in;
    PGPObjectFactory pgpObjectFactory;
    PGPEncryptedDataList pgpEncryptedDataList = null;
    PGPPrivateKey privateKey = null;
    PGPPublicKeyEncryptedData pgpPublicKeyEncryptedData = null;
    Object compressedObject = null;
    PGPLiteralData literalData = null;
    //First get a  PGPEncryptedDataList from the input stream.
    try {
        in = PGPUtil.getDecoderStream(inputStream);
        pgpObjectFactory = new PGPObjectFactory(in, new JcaKeyFingerprintCalculator());
        Object object = pgpObjectFactory.nextObject();
        if (object instanceof PGPEncryptedDataList) {
            //the EncryptedDataList is either the first object;
            pgpEncryptedDataList = (PGPEncryptedDataList) object;
        } else {
            //or the next
            pgpEncryptedDataList = (PGPEncryptedDataList) pgpObjectFactory.nextObject();
        }

        if (pgpEncryptedDataList == null) {
            throw new MinigmaException("couldn't find encrypted data list");
        }
    } catch (Exception e) {
        //Log.d(TAG,"Minigma-unLock() 1: error reading encrypted data list", e);
        throw new MinigmaException("error reading encrypted data list", e);
    }
    // now get encrypted objects from the list.
    try {
        //Log.d(TAG, "Minigma-unLock() 2 start");
        @SuppressWarnings("unchecked")
        Iterator<PGPPublicKeyEncryptedData> it = pgpEncryptedDataList.getEncryptedDataObjects();
        //Log.d(TAG, "Minigma-unLock() 2: EncryptedDataList size = "+Integer.toString(pgpEncryptedDataList.size())+", now got its iterator");
        JcePBESecretKeyDecryptorBuilder keyDecryptorBuilder = new JcePBESecretKeyDecryptorBuilder();
        keyDecryptorBuilder.setProvider(BouncyCastleProvider.PROVIDER_NAME);
        while (it.hasNext() && privateKey == null) {
            pgpPublicKeyEncryptedData = it.next();
            long keyID = pgpPublicKeyEncryptedData.getKeyID();
            //Log.d(TAG, "Minigma-unLock() 2: data was encrypted with key:"+ Long.toHexString(keyID));
            PGPSecretKey secretKey = key.getDecryptionKey(keyID);
            if (secretKey == null) {
                //Log.d(TAG, "Minigma-unLock() 2: bad key, no decryption key");
                throw new DecryptionException("2: bad key, no decryption key");
            }
            if (secretKey.getKeyID() == keyID) {
                privateKey = key.getDecryptionKey(keyID)
                        .extractPrivateKey(keyDecryptorBuilder.build(passphrase));
                //Log.d(TAG,"Minigma-unLock() 2: got private key");
            } else {
                //Log.d(TAG, "Engima-unLock() 2: not this time, round again.");
            }
        }
        if (privateKey == null) {

            throw new DecryptionException("Minigma-unLock() 2: decryption key doesn't fit any of the locks");
        }
    } catch (Exception e) {

        throw new MinigmaException("A problem arose during decryption", e);
    }

    try {

        PublicKeyDataDecryptorFactory dataDecryptorFactory = new BcPublicKeyDataDecryptorFactory(privateKey);
        InputStream decryptedStream = pgpPublicKeyEncryptedData.getDataStream(dataDecryptorFactory);
        JcaPGPObjectFactory compressedFactory = new JcaPGPObjectFactory(decryptedStream);
        compressedObject = compressedFactory.nextObject();

    } catch (Exception e) {

        throw new MinigmaException("Minigma-unLock() 3: error reading encrypted data stream", e);
    }
    try {

        PGPCompressedData clearCompressedData = (PGPCompressedData) compressedObject;
        Object uncompressedObject = null;
        JcaPGPObjectFactory uncompressedFactory = null;

        InputStream inputStream2 = clearCompressedData.getDataStream();

        uncompressedFactory = new JcaPGPObjectFactory(inputStream2);

        uncompressedObject = uncompressedFactory.nextObject();

        if (uncompressedObject instanceof PGPOnePassSignatureList) {
            // and the next object should be literal data:
            uncompressedObject = uncompressedFactory.nextObject();
            if (uncompressedObject instanceof PGPLiteralData) {
                literalData = (PGPLiteralData) uncompressedObject;
            } else {
                //unrecognised object;
                throw new MinigmaException("Minigma-unLock() 4: unrecognised object: A "
                        + uncompressedObject.getClass().getName());

            }
            uncompressedObject = uncompressedFactory.nextObject();
            if (uncompressedObject instanceof PGPSignatureList) {
            } else {
                //unrecognised object;
                throw new MinigmaException(
                        "Minigma-unlock() 4: unrecognised object B " + uncompressedObject.getClass().getName());
            }
        } else if (uncompressedObject instanceof PGPLiteralData) {
            literalData = (PGPLiteralData) uncompressedObject;
        } else {
            //unrecognised object
            throw new MinigmaException(
                    "Minigma-unLock() 4: unrecognised object C " + uncompressedObject.getClass().getName());

        }
    } catch (Exception e) {
        throw new MinigmaException("Minigma-unLock() 4: error getting decompressed object", e);

    }

    InputStream inputStream1 = literalData.getDataStream();
    ByteArrayOutputStream result = new ByteArrayOutputStream();
    byte[] buffer = new byte[1024];
    int length;
    while ((length = inputStream1.read(buffer)) != -1) {
        result.write(buffer, 0, length);
    }
    return result.toString("UTF-8");
}