private byte[] encrypt(byte[] clearData, PGPPublicKey encKey) { try { byte[] compressedData = compress(clearData, CompressionAlgorithmTags.ZIP); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); OutputStream out = new ArmoredOutputStream(bOut); PGPEncryptedDataGenerator encGen = new PGPEncryptedDataGenerator( new BcPGPDataEncryptorBuilder(PGPEncryptedDataGenerator.CAST5) .setSecureRandom(new SecureRandom())); encGen.addMethod(new BcPublicKeyKeyEncryptionMethodGenerator(encKey)); OutputStream encOut = encGen.open(out, compressedData.length); encOut.write(compressedData); encOut.close(); out.close(); return bOut.toByteArray(); } catch (Exception e) { throw new RuntimeException(e); } }
private OutputStream getEncryptionWrapper(OutputStream out) throws IOException, PGPException { final PGPEncryptedDataGenerator encryptedDataGenerator = new PGPEncryptedDataGenerator( new BcPGPDataEncryptorBuilder(symmetricAlgorithm.value()) .setWithIntegrityPacket(true) .setSecureRandom(random)); for (KeySet recipient : recipients) { if (recipient.getSubKey().getKeyID() != owner.getSubKey().getKeyID()) { encryptedDataGenerator.addMethod(new BcPublicKeyKeyEncryptionMethodGenerator(recipient.getSubKey().getPublicKey())); } } encryptedDataGenerator.addMethod(new BcPublicKeyKeyEncryptionMethodGenerator(owner.getSubKey().getPublicKey())); return encryptedDataGenerator.open(out, new byte[BUFFER_SIZE]); }
/** * Builds a PublicKeyKeyEncryptionMethodGenerator * for the specified key. */ protected PublicKeyKeyEncryptionMethodGenerator buildPublicKeyEncryptor( Key key) { if (log.isLoggable(Level.INFO)) log.info("using encryption key " + key.getEncryption()); PGPPublicKey publicKey = key.getEncryption().getPublicKey(); return new BcPublicKeyKeyEncryptionMethodGenerator(publicKey); }
/** * Encrypt the given file * @param unencryptedFileName - Name of the unecrypted file * @param encryptedFileName - Name of the encrypted file, will have .enc as extension * @throws IOException * @throws NoSuchProviderException * @throws PGPException * @throws CryptDecryptException */ public void encryptFile(final String unencryptedFileName, final String encryptedFileName) throws IOException, NoSuchProviderException, PGPException, CryptDecryptException { if(enableDebugLog)Trace.logInfo("CryptDecryptUtil.encryptFile", "Entry"); // Initialise PGP provider and read public key if(!initialized) initialise(false); FileOutputStream encrytedFile = new FileOutputStream(encryptedFileName); // Compress the input plain text file in ZIP format. ByteArrayOutputStream bOut = new ByteArrayOutputStream(); PGPCompressedDataGenerator comData = new PGPCompressedDataGenerator(PGPCompressedData.ZIP); PGPUtil.writeFileToLiteralData(comData.open(bOut), PGPLiteralData.BINARY, new File(unencryptedFileName) ); comData.close(); // Encrypt the file using Triple-DES algorithm BcPGPDataEncryptorBuilder dataEncryptor = new BcPGPDataEncryptorBuilder(PGPEncryptedData.TRIPLE_DES); dataEncryptor.setWithIntegrityPacket(false); dataEncryptor.setSecureRandom(new SecureRandom()); PGPEncryptedDataGenerator encryptedDataGenerator = new PGPEncryptedDataGenerator(dataEncryptor); encryptedDataGenerator.addMethod(new BcPublicKeyKeyEncryptionMethodGenerator(publicKey)); byte[] bytes = bOut.toByteArray(); OutputStream cOut = encryptedDataGenerator.open(encrytedFile, bytes.length); cOut.write(bytes); cOut.close(); encrytedFile.close(); if(enableDebugLog)Trace.logInfo("CryptDecryptUtil.encryptFile", "Exit"); }
/** * Opens a new {@link Encryptor} (Writing Step 1/3) * * <p>This is the first step in creating a ghostryde file. After this method, you'll want to * call {@link #openCompressor(Encryptor)}. * * @param os is the upstream {@link OutputStream} to which the result is written. * @param publicKey is the public encryption key of the recipient. * @throws IOException * @throws PGPException */ @CheckReturnValue public Encryptor openEncryptor(@WillNotClose OutputStream os, PGPPublicKey publicKey) throws IOException, PGPException { PGPEncryptedDataGenerator encryptor = new PGPEncryptedDataGenerator( new JcePGPDataEncryptorBuilder(CIPHER) .setWithIntegrityPacket(USE_INTEGRITY_PACKET) .setSecureRandom(getRandom()) .setProvider(PROVIDER_NAME)); encryptor.addMethod(new BcPublicKeyKeyEncryptionMethodGenerator(publicKey)); return new Encryptor(encryptor.open(os, new byte[bufferSize])); }
@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)); } 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); } } }
public String encrypt(String message, boolean sign) throws PGPEncryptionException, PGPKeyNotFoundException { try { PGPSecretKey secretKey = ourKey.getSecretKey(); PGPPrivateKey privateKey = ourKey.getPrivateKey(); byte[] messageBytes = message.getBytes(StandardCharsets.UTF_8); PGPLiteralDataGenerator literalDataGenerator = new PGPLiteralDataGenerator(); PGPEncryptedDataGenerator encryptedDataGenerator = new PGPEncryptedDataGenerator(dataEncryptor); encryptedDataGenerator.addMethod(new BcPublicKeyKeyEncryptionMethodGenerator(publicKey.getEncryptionKey())); PGPCompressedDataGenerator compressedDataGenerator = new PGPCompressedDataGenerator(PGPCompressedData.ZLIB); PGPContentSignerBuilder signerBuilder = new BcPGPContentSignerBuilder( secretKey.getPublicKey().getAlgorithm(), HashAlgorithmTags.SHA256 ); PGPSignatureGenerator signatureGenerator = new PGPSignatureGenerator(signerBuilder); signatureGenerator.init(PGPSignature.BINARY_DOCUMENT, privateKey); PGPSignatureSubpacketGenerator spGen = new PGPSignatureSubpacketGenerator(); spGen.setSignerUserID(false, (String) secretKey.getPublicKey().getUserIDs().next()); signatureGenerator.setHashedSubpackets(spGen.generate()); if (sign) { signatureGenerator.update(messageBytes); } ByteArrayOutputStream bOut = new ByteArrayOutputStream(); Hashtable<String, String> headers = new Hashtable<>(); headers.put("Version", "QPG"); ArmoredOutputStream armoredOut = new ArmoredOutputStream(bOut, headers); OutputStream encryptedOut = encryptedDataGenerator.open(armoredOut, new byte[BUFFER_SIZE]); OutputStream compressedOut = compressedDataGenerator.open(encryptedOut); if (sign) { signatureGenerator.generateOnePassVersion(false).encode(compressedOut); } OutputStream literalOut = literalDataGenerator.open( compressedOut, PGPLiteralData.UTF8, PGPLiteralData.CONSOLE, messageBytes.length, new Date() ); literalOut.write(messageBytes); literalDataGenerator.close(); if (sign) { signatureGenerator.generate().encode(compressedOut); } compressedDataGenerator.close(); encryptedDataGenerator.close(); armoredOut.close(); return new String(bOut.toByteArray(), StandardCharsets.UTF_8); } catch (PGPException | RuntimeException | IOException e) { throw new PGPEncryptionException("Error encrypting message", e); } }
@Test public void encryptAndDecrypt() throws Exception { // both keys have property encryptionKey==true final String[] keyIds = { "d7a92a24aa97ddbd", // master-key "a58da7d810b74edf" // sub-key }; for (final String keyId : keyIds) { final PGPDataEncryptorBuilder encryptorBuilder = new BcPGPDataEncryptorBuilder(SymmetricKeyAlgorithmTags.TWOFISH); final PGPEncryptedDataGenerator encryptedDataGenerator = new PGPEncryptedDataGenerator(encryptorBuilder); final PGPKeyEncryptionMethodGenerator keyEncryptionMethodGenerator = new BcPublicKeyKeyEncryptionMethodGenerator( getPgpPublicKeyOrFail(bytesToLong(decodeHexStr(keyId)))); encryptedDataGenerator.addMethod(keyEncryptionMethodGenerator); final byte[] plain = new byte[1 + random.nextInt(1024 * 1024)]; random.nextBytes(plain); final File encryptedFile = File.createTempFile("encrypted_", ".tmp"); try (final OutputStream encryptedOut = new FileOutputStream(encryptedFile);) { try (final OutputStream plainOut = encryptedDataGenerator.open(encryptedOut, new byte[1024 * 16]);) { plainOut.write(plain); } } final byte[] decrypted; try (InputStream in = new FileInputStream(encryptedFile)) { final PGPEncryptedDataList encryptedDataList = new PGPEncryptedDataList(new BCPGInputStream(in)); final Iterator<?> encryptedDataObjects = encryptedDataList.getEncryptedDataObjects(); assertThat(encryptedDataObjects.hasNext()).isTrue(); final PGPPublicKeyEncryptedData encryptedData = (PGPPublicKeyEncryptedData) encryptedDataObjects.next(); assertThat(encryptedDataObjects.hasNext()).isFalse(); final PublicKeyDataDecryptorFactory dataDecryptorFactory = new BcPublicKeyDataDecryptorFactory( getPgpPrivateKeyOrFail(encryptedData.getKeyID(), "test12345".toCharArray())); try (InputStream plainIn = encryptedData.getDataStream(dataDecryptorFactory);) { final ByteArrayOutputStream out = new ByteArrayOutputStream(); transferStreamData(plainIn, out); decrypted = out.toByteArray(); } } assertThat(decrypted).isEqualTo(plain); encryptedFile.delete(); // delete it, if this test did not fail } }
/** * Encrypt, sign and write input stream data to output stream. * Input and output stream are closed. */ private static void encryptAndSign( InputStream plainInput, OutputStream encryptedOutput, PersonalKey myKey, List<PGPUtils.PGPCoderKey> receiverKeys) throws IOException, PGPException { // setup data encryptor & generator BcPGPDataEncryptorBuilder encryptor = new BcPGPDataEncryptorBuilder(PGPEncryptedData.AES_192); encryptor.setWithIntegrityPacket(true); encryptor.setSecureRandom(new SecureRandom()); // add public key recipients PGPEncryptedDataGenerator encGen = new PGPEncryptedDataGenerator(encryptor); receiverKeys.forEach(key -> encGen.addMethod(new BcPublicKeyKeyEncryptionMethodGenerator(key.encryptKey))); OutputStream encryptedOut = encGen.open(encryptedOutput, new byte[BUFFER_SIZE]); // setup compressed data generator PGPCompressedDataGenerator compGen = new PGPCompressedDataGenerator(PGPCompressedData.ZIP); OutputStream compressedOut = compGen.open(encryptedOut, new byte[BUFFER_SIZE]); // setup signature generator int algo = myKey.getSigningAlgorithm(); PGPSignatureGenerator sigGen = new PGPSignatureGenerator( new BcPGPContentSignerBuilder(algo, HashAlgorithmTags.SHA256)); sigGen.init(PGPSignature.BINARY_DOCUMENT, myKey.getPrivateSigningKey()); PGPSignatureSubpacketGenerator spGen = new PGPSignatureSubpacketGenerator(); spGen.setSignerUserID(false, myKey.getUserId()); sigGen.setUnhashedSubpackets(spGen.generate()); sigGen.generateOnePassVersion(false).encode(compressedOut); // Initialize literal data generator PGPLiteralDataGenerator literalGen = new PGPLiteralDataGenerator(); OutputStream literalOut = literalGen.open( compressedOut, PGPLiteralData.BINARY, "", new Date(), new byte[BUFFER_SIZE]); // read the "in" stream, compress, encrypt and write to the "out" stream // this must be done if clear data is bigger than the buffer size // but there are other ways to optimize... byte[] buf = new byte[BUFFER_SIZE]; int len; while ((len = plainInput.read(buf)) > 0) { literalOut.write(buf, 0, len); sigGen.update(buf, 0, len); } literalGen.close(); // generate the signature, compress, encrypt and write to the "out" stream sigGen.generate().encode(compressedOut); compGen.close(); encGen.close(); }