package de.unioninvestment.crud2go.spi.security.pgp; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.security.GeneralSecurityException; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.SecureRandom; import java.security.Security; import java.util.Date; import java.util.Iterator; import org.bouncycastle.bcpg.ArmoredOutputStream; import org.bouncycastle.bcpg.CompressionAlgorithmTags; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.openpgp.PGPCompressedData; import org.bouncycastle.openpgp.PGPCompressedDataGenerator; import org.bouncycastle.openpgp.PGPEncryptedData; 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.PGPObjectFactory; import org.bouncycastle.openpgp.PGPPrivateKey; import org.bouncycastle.openpgp.PGPPublicKey; import org.bouncycastle.openpgp.PGPPublicKeyEncryptedData; import org.bouncycastle.openpgp.PGPSecretKey; import org.bouncycastle.openpgp.PGPSecretKeyRingCollection; import org.bouncycastle.openpgp.PGPSignature; import org.bouncycastle.openpgp.PGPUtil; public final class PGPCryptoUtil { public static final char[] EMPTY_PASSPHRASE = new char[0]; private static final int BUFFER_SIZE = 1 << 16; static { if (Security.getProvider(PGPUtil.getDefaultProvider()) == null) { Security.addProvider(new BouncyCastleProvider()); } } public static void exportRSAKeyPair(OutputStream secretFile, OutputStream publicFile, int strength, String identity) throws GeneralSecurityException, PGPException, IOException { KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA", PGPUtil.getDefaultProvider()); kpg.initialize(strength); KeyPair kp = kpg.generateKeyPair(); PGPSecretKey secretKey = new PGPSecretKey( PGPSignature.DEFAULT_CERTIFICATION, PGPPublicKey.RSA_GENERAL, kp.getPublic(), kp.getPrivate(), new Date(), identity, PGPEncryptedData.CAST5, EMPTY_PASSPHRASE, null, null, new SecureRandom(), "BC"); PGPPublicKey publicKey = secretKey.getPublicKey(); OutputStream secretPublicOut = new ArmoredOutputStream(secretFile); publicKey.encode(secretPublicOut); secretPublicOut.close(); OutputStream secretOut = new ArmoredOutputStream(secretFile); secretKey.encode(secretOut); secretOut.close(); OutputStream publicOut = new ArmoredOutputStream(publicFile); publicKey.encode(publicOut); publicOut.close(); } public static byte[] decrypt(byte[] message, PGPSecretKeyRingCollection secretKeys, char[] passphrase) throws GeneralSecurityException, PGPException, IOException { return internalDecrypt(message, secretKeys, passphrase); } public static byte[] internalDecrypt(byte[] message, PGPSecretKeyRingCollection secretKeys, char[] passphrase) throws GeneralSecurityException, PGPException, IOException { ByteArrayOutputStream out = new ByteArrayOutputStream(); InputStream in = PGPUtil.getDecoderStream(new ByteArrayInputStream( message)); PGPObjectFactory factory = new PGPObjectFactory(in); PGPEncryptedDataList enc; Object object = factory.nextObject(); if (object instanceof PGPEncryptedDataList) { enc = (PGPEncryptedDataList) object; } else { enc = (PGPEncryptedDataList) factory.nextObject(); } Iterator it = enc.getEncryptedDataObjects(); PGPPublicKeyEncryptedData encryptedData = null; PGPPrivateKey privateKey = null; while (privateKey == null && it.hasNext()) { encryptedData = (PGPPublicKeyEncryptedData) it.next(); PGPSecretKey secretKey = secretKeys.getSecretKey(encryptedData .getKeyID()); if (secretKey != null) { privateKey = secretKey.extractPrivateKey(passphrase, PGPUtil.getDefaultProvider()); } } if (privateKey == null) { throw new IllegalArgumentException( "Private key for message not found!"); } InputStream clear = encryptedData.getDataStream(privateKey, PGPUtil.getDefaultProvider()); factory = new PGPObjectFactory(clear); object = factory.nextObject(); if (object instanceof PGPCompressedData) { factory = new PGPObjectFactory( ((PGPCompressedData) object).getDataStream()); } while ((object = factory.nextObject()) != null) { if (object instanceof PGPLiteralData) { out = Utils.read(((PGPLiteralData) object).getDataStream()); } } return out.toByteArray(); } public static byte[] encrypt(byte[] message, PGPPublicKey[] publicKeys, int cipher) throws GeneralSecurityException, PGPException, IOException { return encrypt(message, publicKeys, cipher, null); } public static byte[] encrypt(byte[] message, PGPPublicKey[] publicKeys, int cipher, String filename) throws GeneralSecurityException, PGPException, IOException { return internalEncrypt(message, publicKeys, cipher, filename); } private static byte[] internalEncrypt(byte[] message, PGPPublicKey[] publicKeys, int cipher, String filename) throws GeneralSecurityException, PGPException, IOException { ByteArrayOutputStream out = new ByteArrayOutputStream(); OutputStream amoOut = new ArmoredOutputStream(out); PGPEncryptedDataGenerator encDataGen = new PGPEncryptedDataGenerator( cipher, true, new SecureRandom(), PGPUtil.getDefaultProvider()); for (PGPPublicKey publicKey : publicKeys) { encDataGen.addMethod(publicKey); } OutputStream encOut = encDataGen.open(amoOut, new byte[BUFFER_SIZE]); PGPCompressedDataGenerator comDataGen = new PGPCompressedDataGenerator( CompressionAlgorithmTags.ZIP); OutputStream comOut = comDataGen.open(encOut, new byte[BUFFER_SIZE]); PGPLiteralDataGenerator litDataGen = new PGPLiteralDataGenerator(); OutputStream litOut = litDataGen.open(comOut, PGPLiteralDataGenerator.BINARY, (filename != null ? filename : PGPLiteralDataGenerator.CONSOLE), PGPLiteralDataGenerator.NOW, new byte[BUFFER_SIZE]); litOut.write(message); litDataGen.close(); comDataGen.close(); encDataGen.close(); amoOut.close(); return out.toByteArray(); } }