List of usage examples for org.bouncycastle.openpgp PGPPublicKeyEncryptedData getKeyID
public long getKeyID()
From source file:org.mule.module.pgp.DecryptStreamTransformer.java
License:Open Source License
/** * {@inheritDoc}//from ww w .j a va 2s. c o m */ @Override public void initialize(OutputStream out) throws Exception { InputStream decodedInputStream = PGPUtil.getDecoderStream(this.toBeDecrypted); PGPObjectFactory pgpF = new PGPObjectFactory(decodedInputStream); Object o = pgpF.nextObject(); if (o == null) { throw new IllegalArgumentException("Invalid PGP message"); } // the first object might be a PGP marker packet. PGPEncryptedDataList enc; if (o instanceof PGPEncryptedDataList) { enc = (PGPEncryptedDataList) o; } else { enc = (PGPEncryptedDataList) pgpF.nextObject(); } // This loop looks like it is ready for multiple encrypted // objects, but really only one is expected. Iterator<?> it = enc.getEncryptedDataObjects(); PGPPublicKeyEncryptedData pbe = null; PGPPrivateKey privateKey = null; while (privateKey == null && it.hasNext()) { pbe = (PGPPublicKeyEncryptedData) it.next(); privateKey = getPrivateKey(pbe.getKeyID(), this.password); if (privateKey == null) { throw new IllegalArgumentException("Failed to find private key with ID " + pbe.getKeyID()); } } clearStream = pbe.getDataStream(privateKey, "BC"); PGPObjectFactory plainFact = new PGPObjectFactory(clearStream); o = plainFact.nextObject(); PGPOnePassSignature signature = null; if (o instanceof PGPOnePassSignatureList) { PGPOnePassSignatureList list = (PGPOnePassSignatureList) o; signature = list.get(0); signature.initVerify(this.publicKey, "BC"); // TODO verify signature // signature.verify(null); o = plainFact.nextObject(); } compressedStream = null; if (o instanceof PGPCompressedData) { PGPCompressedData cData = (PGPCompressedData) o; compressedStream = new BufferedInputStream(cData.getDataStream()); PGPObjectFactory pgpFact = new PGPObjectFactory(compressedStream); Object streamData = pgpFact.nextObject(); o = streamData; } if (o instanceof PGPLiteralData) { PGPLiteralData ld = (PGPLiteralData) o; uncStream = ld.getInputStream(); } else { throw new PGPException("input is not PGPLiteralData - type unknown."); } }
From source file:org.opentestsystem.delivery.testreg.transformer.GpgVerifier.java
License:Open Source License
public byte[] decryptAndVerify(File encryptedSignedFile) throws IOException, SignatureException, PGPException { byte[] output = null; InputStream in = PGPUtil.getDecoderStream(new FileInputStream(encryptedSignedFile)); InputStream publicKeyIn = encryptor.getStreamForPath(publicKeyringLocation); ByteArrayOutputStream fOut = new ByteArrayOutputStream(); PGPObjectFactory pgpF = new PGPObjectFactory(in); PGPEncryptedDataList enc;/*from w w w. j ava2s . c o m*/ Object o = pgpF.nextObject(); // // the first object might be a PGP marker packet. // while (!(o instanceof PGPEncryptedDataList)) { o = pgpF.nextObject(); } if (o instanceof PGPEncryptedDataList) { enc = (PGPEncryptedDataList) o; } else { enc = (PGPEncryptedDataList) pgpF.nextObject(); } // // find the secret key // Iterator<?> it = enc.getEncryptedDataObjects(); PGPPrivateKey sKey = null; PGPPublicKeyEncryptedData pbe = null; while (sKey == null && it.hasNext()) { pbe = (PGPPublicKeyEncryptedData) it.next(); InputStream secretKeyringInputStream = encryptor.getStreamForPath(secretKeyringLocation); PGPSecretKeyRingCollection pgpSec = new PGPSecretKeyRingCollection( PGPUtil.getDecoderStream(secretKeyringInputStream)); PGPSecretKey pgpSecKey = pgpSec.getSecretKey(pbe.getKeyID()); if (pgpSecKey == null) { fail("could not find secret key"); } PBESecretKeyDecryptor decryptor = new BcPBESecretKeyDecryptorBuilder( new BcPGPDigestCalculatorProvider()).build(LANDINGZONE_PASS); sKey = pgpSecKey.extractPrivateKey(decryptor); } if (sKey == null) { throw new IllegalArgumentException("secret key for message not found."); } InputStream clear = pbe .getDataStream(new JcePublicKeyDataDecryptorFactoryBuilder().setProvider("BC").build(sKey)); PGPObjectFactory plainFact = new PGPObjectFactory(clear); Object message = null; PGPOnePassSignatureList onePassSignatureList = null; PGPSignatureList signatureList = null; PGPCompressedData compressedData = null; message = plainFact.nextObject(); ByteArrayOutputStream actualOutput = new ByteArrayOutputStream(); while (message != null) { LOGGER.debug("decrypted message: " + message.toString()); if (message instanceof PGPCompressedData) { compressedData = (PGPCompressedData) message; plainFact = new PGPObjectFactory(compressedData.getDataStream()); message = plainFact.nextObject(); } if (message instanceof PGPLiteralData) { // have to read it and keep it somewhere. Streams.pipeAll(((PGPLiteralData) message).getInputStream(), actualOutput); } else if (message instanceof PGPOnePassSignatureList) { onePassSignatureList = (PGPOnePassSignatureList) message; } else if (message instanceof PGPSignatureList) { signatureList = (PGPSignatureList) message; } else { throw new PGPException("message unknown message type."); } message = plainFact.nextObject(); } actualOutput.close(); PGPPublicKey publicKey = null; output = actualOutput.toByteArray(); if (onePassSignatureList == null || signatureList == null) { throw new PGPException("Signatures not found."); } else { for (int i = 0; i < onePassSignatureList.size(); i++) { PGPOnePassSignature ops = onePassSignatureList.get(0); LOGGER.debug("verifier : " + ops.getKeyID()); PGPPublicKeyRingCollection pgpRing = new PGPPublicKeyRingCollection( PGPUtil.getDecoderStream(publicKeyIn)); publicKey = pgpRing.getPublicKey(ops.getKeyID()); if (publicKey != null) { ops.init(new JcaPGPContentVerifierBuilderProvider().setProvider("BC"), publicKey); ops.update(output); PGPSignature signature = signatureList.get(i); // apparently the signature can only be verified once?? if the verify method is called a 2nd time it // will fail boolean signatureVerified = ops.verify(signature); assertThat(signatureVerified, is(true)); if (signatureVerified) { Iterator<?> userIds = publicKey.getUserIDs(); while (userIds.hasNext()) { String userId = (String) userIds.next(); LOGGER.debug("Signed by " + userId); } LOGGER.debug("Signature verified"); } else { throw new SignatureException("Signature verification failed"); } } } } if (pbe.isIntegrityProtected() && !pbe.verify()) { throw new PGPException("Data is integrity protected but integrity is lost."); } else if (publicKey == null) { throw new SignatureException("Signature not found"); } else { fOut.write(output); fOut.flush(); fOut.close(); LOGGER.debug("decrypt and verify output: " + fOut.toString()); } return output; }
From source file:org.pgptool.gui.encryption.implpgp.EncryptionServicePgpImpl.java
License:Open Source License
@SuppressWarnings("rawtypes") @Override/*from w w w .j a v a 2 s. c o m*/ public Set<String> findKeyIdsForDecryption(InputStream inputStream) { Preconditions.checkArgument(inputStream != null, "Input stream must not be null"); try { PGPObjectFactory factory = new PGPObjectFactory(PGPUtil.getDecoderStream(inputStream), KeyFilesOperationsPgpImpl.fingerprintCalculator); for (Iterator iter = factory.iterator(); iter.hasNext();) { Object section = iter.next(); log.debug(section); if (section instanceof PGPEncryptedDataList) { PGPEncryptedDataList d = (PGPEncryptedDataList) section; HashSet<String> ret = new HashSet<>(); for (Iterator dataIter = d.getEncryptedDataObjects(); dataIter.hasNext();) { PGPPublicKeyEncryptedData data = (PGPPublicKeyEncryptedData) dataIter.next(); ret.add(KeyDataPgp.buildKeyIdStr(data.getKeyID())); } log.debug("Possible decryption with IDS: " + Arrays.toString(ret.toArray())); return ret; } } throw new RuntimeException("Information about decryption methods was not found"); } catch (Throwable t) { throw new RuntimeException("This file doesn't look like encrypted file OR format is not supported", t); } }
From source file:org.pgptool.gui.encryption.implpgp.EncryptionServicePgpImpl.java
License:Open Source License
@SuppressWarnings("rawtypes") private PGPPublicKeyEncryptedData getPublicKeyEncryptedDataByKeyId(InputStream in, PGPSecretKey secretKey) { try {// w w w. j a v a 2 s .c o m PGPObjectFactory factory = new PGPObjectFactory(PGPUtil.getDecoderStream(in), KeyFilesOperationsPgpImpl.fingerprintCalculator); for (Iterator iter = factory.iterator(); iter.hasNext();) { Object section = iter.next(); if (section instanceof PGPEncryptedDataList) { PGPEncryptedDataList d = (PGPEncryptedDataList) section; for (Iterator dataIter = d.getEncryptedDataObjects(); dataIter.hasNext();) { PGPPublicKeyEncryptedData data = (PGPPublicKeyEncryptedData) dataIter.next(); if (data.getKeyID() == secretKey.getKeyID()) { return data; } } } } // NOTE: That is actually should NEVER happen since secret key we're // supposed to use here was taken exactly same way as we're looking // for PGPPublicKeyEncryptedData now throw new RuntimeException("Encryption data matching given key " + KeyDataPgp.buildKeyIdStr(secretKey.getKeyID()) + " wasn't found"); } catch (Throwable t) { throw new RuntimeException("Failed to find Encryption data section in encrypted file", t); } }
From source file:org.sufficientlysecure.keychain.pgp.PgpDecryptVerifyOperation.java
License:Open Source License
private EncryptStreamResult handleEncryptedPacket(PgpDecryptVerifyInputParcel input, CryptoInputParcel cryptoInput, PGPEncryptedDataList enc, OperationLog log, int indent, boolean useBackupCode) throws PGPException { EncryptStreamResult result = new EncryptStreamResult(); boolean asymmetricPacketFound = false; boolean symmetricPacketFound = false; boolean anyPacketFound = false; boolean decryptedSessionKeyAvailable = false; PGPPublicKeyEncryptedData encryptedDataAsymmetric = null; PGPPBEEncryptedData encryptedDataSymmetric = null; CanonicalizedSecretKey decryptionKey = null; CachingDataDecryptorFactory cachedKeyDecryptorFactory = new CachingDataDecryptorFactory( Constants.BOUNCY_CASTLE_PROVIDER_NAME, cryptoInput.getCryptoData()); ;//from w ww. j av a 2 s .com Passphrase passphrase = null; Iterator<?> it = enc.getEncryptedDataObjects(); // go through all objects and find one we can decrypt while (it.hasNext()) { Object obj = it.next(); if (obj instanceof PGPPublicKeyEncryptedData) { anyPacketFound = true; PGPPublicKeyEncryptedData encData = (PGPPublicKeyEncryptedData) obj; long subKeyId = encData.getKeyID(); log.add(LogType.MSG_DC_ASYM, indent, KeyFormattingUtils.convertKeyIdToHex(subKeyId)); decryptedSessionKeyAvailable = cachedKeyDecryptorFactory.hasCachedSessionData(encData); if (decryptedSessionKeyAvailable) { asymmetricPacketFound = true; encryptedDataAsymmetric = encData; break; } CachedPublicKeyRing cachedPublicKeyRing; try { // get actual keyring object based on master key id cachedPublicKeyRing = mProviderHelper .getCachedPublicKeyRing(KeyRings.buildUnifiedKeyRingsFindBySubkeyUri(subKeyId)); long masterKeyId = cachedPublicKeyRing.getMasterKeyId(); // allow only specific keys for decryption? if (input.getAllowedKeyIds() != null) { Log.d(Constants.TAG, "encData.getKeyID(): " + subKeyId); Log.d(Constants.TAG, "mAllowedKeyIds: " + input.getAllowedKeyIds()); Log.d(Constants.TAG, "masterKeyId: " + masterKeyId); if (!input.getAllowedKeyIds().contains(masterKeyId)) { // this key is in our db, but NOT allowed! // continue with the next packet in the while loop result.skippedDisallowedKey = true; log.add(LogType.MSG_DC_ASKIP_NOT_ALLOWED, indent + 1); continue; } } SecretKeyType secretKeyType = cachedPublicKeyRing.getSecretKeyType(subKeyId); if (!secretKeyType.isUsable()) { decryptionKey = null; log.add(LogType.MSG_DC_ASKIP_UNAVAILABLE, indent + 1); continue; } // get actual subkey which has been used for this encryption packet CanonicalizedSecretKeyRing canonicalizedSecretKeyRing = mProviderHelper .getCanonicalizedSecretKeyRing(masterKeyId); CanonicalizedSecretKey candidateDecryptionKey = canonicalizedSecretKeyRing .getSecretKey(subKeyId); if (!candidateDecryptionKey.canEncrypt()) { log.add(LogType.MSG_DC_ASKIP_BAD_FLAGS, indent + 1); continue; } if (secretKeyType == SecretKeyType.DIVERT_TO_CARD) { passphrase = null; } else if (secretKeyType == SecretKeyType.PASSPHRASE_EMPTY) { passphrase = new Passphrase(""); } else if (cryptoInput.hasPassphrase()) { passphrase = cryptoInput.getPassphrase(); } else { // if no passphrase was explicitly set try to get it from the cache service try { // returns "" if key has no passphrase passphrase = getCachedPassphrase(subKeyId); log.add(LogType.MSG_DC_PASS_CACHED, indent + 1); } catch (PassphraseCacheInterface.NoSecretKeyException e) { log.add(LogType.MSG_DC_ERROR_NO_KEY, indent + 1); return result.with(new DecryptVerifyResult(DecryptVerifyResult.RESULT_ERROR, log)); } // if passphrase was not cached, return here indicating that a passphrase is missing! if (passphrase == null) { log.add(LogType.MSG_DC_PENDING_PASSPHRASE, indent + 1); return result.with(new DecryptVerifyResult(log, RequiredInputParcel.createRequiredDecryptPassphrase(masterKeyId, subKeyId), cryptoInput)); } } // check for insecure encryption key if (!PgpSecurityConstants.isSecureKey(candidateDecryptionKey)) { log.add(LogType.MSG_DC_INSECURE_KEY, indent + 1); result.insecureEncryptionKey = true; } // we're good, write down the data for later asymmetricPacketFound = true; encryptedDataAsymmetric = encData; decryptionKey = candidateDecryptionKey; } catch (PgpKeyNotFoundException | ProviderHelper.NotFoundException e) { // continue with the next packet in the while loop log.add(LogType.MSG_DC_ASKIP_NO_KEY, indent + 1); continue; } // break out of while, only decrypt the first packet where we have a key break; } else if (obj instanceof PGPPBEEncryptedData) { anyPacketFound = true; log.add(LogType.MSG_DC_SYM, indent); if (!input.isAllowSymmetricDecryption()) { log.add(LogType.MSG_DC_SYM_SKIP, indent + 1); continue; } /* * When mAllowSymmetricDecryption == true and we find a data packet here, * we do not search for other available asymmetric packets! */ symmetricPacketFound = true; encryptedDataSymmetric = (PGPPBEEncryptedData) obj; // if no passphrase is given, return here // indicating that a passphrase is missing! if (!cryptoInput.hasPassphrase()) { try { passphrase = getCachedPassphrase(key.symmetric); log.add(LogType.MSG_DC_PASS_CACHED, indent + 1); } catch (PassphraseCacheInterface.NoSecretKeyException e) { // nvm } if (passphrase == null) { log.add(LogType.MSG_DC_PENDING_PASSPHRASE, indent + 1); RequiredInputParcel requiredInputParcel = useBackupCode ? RequiredInputParcel.createRequiredBackupCode() : RequiredInputParcel.createRequiredSymmetricPassphrase(); return result.with(new DecryptVerifyResult(log, requiredInputParcel, cryptoInput)); } } else { passphrase = cryptoInput.getPassphrase(); } // break out of while, only decrypt the first packet break; } } // More data, just acknowledge and ignore. while (it.hasNext()) { Object obj = it.next(); if (obj instanceof PGPPublicKeyEncryptedData) { PGPPublicKeyEncryptedData encData = (PGPPublicKeyEncryptedData) obj; long subKeyId = encData.getKeyID(); log.add(LogType.MSG_DC_TRAIL_ASYM, indent, KeyFormattingUtils.convertKeyIdToHex(subKeyId)); } else if (obj instanceof PGPPBEEncryptedData) { log.add(LogType.MSG_DC_TRAIL_SYM, indent); } else { log.add(LogType.MSG_DC_TRAIL_UNKNOWN, indent); } } // we made sure above one of these two would be true if (symmetricPacketFound) { PGPDigestCalculatorProvider digestCalcProvider = new JcaPGPDigestCalculatorProviderBuilder() .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(); PBEDataDecryptorFactory decryptorFactory = new JcePBEDataDecryptorFactoryBuilder(digestCalcProvider) .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(passphrase.getCharArray()); try { result.cleartextStream = encryptedDataSymmetric.getDataStream(decryptorFactory); } catch (PGPDataValidationException e) { log.add(LogType.MSG_DC_ERROR_SYM_PASSPHRASE, indent + 1); RequiredInputParcel requiredInputParcel = useBackupCode ? RequiredInputParcel.createRequiredBackupCode() : RequiredInputParcel.createRequiredSymmetricPassphrase(); return result.with(new DecryptVerifyResult(log, requiredInputParcel, cryptoInput)); } result.encryptedData = encryptedDataSymmetric; result.symmetricEncryptionAlgo = encryptedDataSymmetric.getSymmetricAlgorithm(decryptorFactory); } else if (asymmetricPacketFound) { CachingDataDecryptorFactory decryptorFactory; if (decryptedSessionKeyAvailable) { decryptorFactory = cachedKeyDecryptorFactory; } else { try { log.add(LogType.MSG_DC_UNLOCKING, indent + 1); if (!decryptionKey.unlock(passphrase)) { log.add(LogType.MSG_DC_ERROR_BAD_PASSPHRASE, indent + 1); return result.with(new DecryptVerifyResult(DecryptVerifyResult.RESULT_ERROR, log)); } } catch (PgpGeneralException e) { log.add(LogType.MSG_DC_ERROR_EXTRACT_KEY, indent + 1); return result.with(new DecryptVerifyResult(DecryptVerifyResult.RESULT_ERROR, log)); } decryptorFactory = decryptionKey.getCachingDecryptorFactory(cryptoInput); // special case: if the decryptor does not have a session key cached for this encrypted // data, and can't actually decrypt on its own, return a pending intent if (!decryptorFactory.canDecrypt() && !decryptorFactory.hasCachedSessionData(encryptedDataAsymmetric)) { log.add(LogType.MSG_DC_PENDING_NFC, indent + 1); return result.with(new DecryptVerifyResult(log, RequiredInputParcel.createSecurityTokenDecryptOperation( decryptionKey.getRing().getMasterKeyId(), decryptionKey.getKeyId(), encryptedDataAsymmetric.getSessionKey()[0]), cryptoInput)); } } try { result.cleartextStream = encryptedDataAsymmetric.getDataStream(decryptorFactory); } catch (PGPKeyValidationException | ArrayIndexOutOfBoundsException e) { log.add(LogType.MSG_DC_ERROR_CORRUPT_DATA, indent + 1); return result.with(new DecryptVerifyResult(DecryptVerifyResult.RESULT_ERROR, log)); } result.symmetricEncryptionAlgo = encryptedDataAsymmetric.getSymmetricAlgorithm(decryptorFactory); result.encryptedData = encryptedDataAsymmetric; Map<ByteBuffer, byte[]> cachedSessionKeys = decryptorFactory.getCachedSessionKeys(); cryptoInput.addCryptoData(cachedSessionKeys); if (cachedSessionKeys.size() >= 1) { Entry<ByteBuffer, byte[]> entry = cachedSessionKeys.entrySet().iterator().next(); result.sessionKey = entry.getKey().array(); result.decryptedSessionKey = entry.getValue(); } } else { // there wasn't even any useful data if (!anyPacketFound) { log.add(LogType.MSG_DC_ERROR_NO_DATA, indent + 1); return result.with(new DecryptVerifyResult(DecryptVerifyResult.RESULT_NO_DATA, log)); } // there was data but key wasn't allowed if (result.skippedDisallowedKey) { log.add(LogType.MSG_DC_ERROR_NO_KEY, indent + 1); return result.with(new DecryptVerifyResult(DecryptVerifyResult.RESULT_KEY_DISALLOWED, log)); } // no packet has been found where we have the corresponding secret key in our db log.add(LogType.MSG_DC_ERROR_NO_KEY, indent + 1); return result.with(new DecryptVerifyResult(DecryptVerifyResult.RESULT_ERROR, log)); } return result; }
From source file:org.tramaci.onionmail.PGP.java
License:Open Source License
@SuppressWarnings({ "rawtypes", "deprecation" }) public static byte[] decrypt(byte[] encrypted, InputStream keyIn, char[] password) throws Exception { InputStream inb = new ByteArrayInputStream(encrypted); InputStream in = PGPUtil.getDecoderStream(inb); try {//w w w. ja v a2 s .co m PGPObjectFactory pgpF = new PGPObjectFactory(in); PGPEncryptedDataList enc = null; Object o = pgpF.nextObject(); if (o == null) throw new Exception("@550 No data in message"); if (o instanceof PGPEncryptedDataList) enc = (PGPEncryptedDataList) o; else enc = (PGPEncryptedDataList) pgpF.nextObject(); //deadcode: if (o==null) throw new Exception("@550 No dataList in message"); Iterator it = enc.getEncryptedDataObjects(); PGPPrivateKey sKey = null; PGPPublicKeyEncryptedData pbe = null; PGPSecretKeyRingCollection pgpSec = new PGPSecretKeyRingCollection(PGPUtil.getDecoderStream(keyIn)); while (sKey == null && it.hasNext()) { pbe = (PGPPublicKeyEncryptedData) it.next(); sKey = findSecretKey(pgpSec, pbe.getKeyID(), password); } if (sKey == null) throw new IllegalArgumentException("@550 SecretKey not found"); InputStream clear = pbe.getDataStream(sKey, "BC"); PGPObjectFactory pgpFact = new PGPObjectFactory(clear); PGPCompressedData cData = (PGPCompressedData) pgpFact.nextObject(); pgpFact = new PGPObjectFactory(cData.getDataStream()); PGPLiteralData ld = (PGPLiteralData) pgpFact.nextObject(); InputStream unc = ld.getInputStream(); ByteArrayOutputStream out = new ByteArrayOutputStream(); int ch; while ((ch = unc.read()) >= 0) { out.write(ch); } byte[] rs = out.toByteArray(); try { in.close(); } catch (Exception I) { } try { inb.close(); } catch (Exception I) { } out.close(); return rs; } catch (Exception E) { try { in.close(); } catch (Exception I) { } try { inb.close(); } catch (Exception I) { } throw E; } }
From source file:ubicrypt.core.crypto.PGPEC.java
License:Open Source License
public static InputStream decrypt(final PGPPrivateKey privateKey, final InputStream cipherText) throws PGPException { final JcaPGPObjectFactory pgpF = new JcaPGPObjectFactory(cipherText); try {// www . j av a 2s . co m final PGPEncryptedDataList encList = (PGPEncryptedDataList) pgpF.nextObject(); log.trace("decrypt with sk:{}", privateKey.getKeyID()); final PGPPublicKeyEncryptedData encP = toStream( (Iterator<PGPPublicKeyEncryptedData>) encList.iterator()) .filter((PGPPublicKeyEncryptedData ed) -> { log.debug("pgp message encrypted with key:{}", ed.getKeyID()); return ed.getKeyID() == privateKey.getKeyID(); }).findFirst().orElseThrow(() -> new PGPException( "the message is not encrypted with the related public key")); try (InputStream clear = encP.getDataStream( new JcePublicKeyDataDecryptorFactoryBuilder().setProvider("BC").build(privateKey))) { Object next = new JcaPGPObjectFactory(clear).nextObject(); if (next instanceof PGPCompressedData) { next = new JcaPGPObjectFactory(((PGPCompressedData) next).getDataStream()).nextObject(); } return ((PGPLiteralData) next).getInputStream(); } } catch (final PGPException e) { throw e; } catch (final Exception e) { Throwables.propagate(e); } return null; }
From source file:uk.co.platosys.dinigma.CryptoEngine.java
License:GNU General Public License
/** * Decrypts an InputStream to a Document * * @param inputStream/*from ww w.ja v a 2s. 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"); }