de.sandmage.opportunisticmail.crypto.OpenPGP.java Source code

Java tutorial

Introduction

Here is the source code for de.sandmage.opportunisticmail.crypto.OpenPGP.java

Source

/*******************************************************************************
 * Copyright (c) 2015 Lennart Riecken
 *
 * This file is part of OpportunisticMail.
 *
 * OpportunisticMail is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * OpportunisticMail is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with OpportunisticMail.  If not, see <http://www.gnu.org/licenses/>.
 *******************************************************************************/

package de.sandmage.opportunisticmail.crypto;

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.security.Security;
import java.util.Date;
import java.util.Iterator;

import org.apache.commons.codec.binary.Base64;
import org.bouncycastle.bcpg.ArmoredOutputStream;
import org.bouncycastle.bcpg.CompressionAlgorithmTags;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.openpgp.PGPCompressedDataGenerator;
import org.bouncycastle.openpgp.PGPEncryptedData;
import org.bouncycastle.openpgp.PGPEncryptedDataGenerator;
import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPLiteralData;
import org.bouncycastle.openpgp.PGPLiteralDataGenerator;
import org.bouncycastle.openpgp.PGPPublicKey;
import org.bouncycastle.openpgp.PGPPublicKeyRing;
import org.bouncycastle.openpgp.PGPPublicKeyRingCollection;
import org.bouncycastle.openpgp.PGPUtil;
import org.bouncycastle.openpgp.operator.jcajce.JcaKeyFingerprintCalculator;
import org.bouncycastle.openpgp.operator.jcajce.JcePGPDataEncryptorBuilder;
import org.bouncycastle.openpgp.operator.jcajce.JcePublicKeyKeyEncryptionMethodGenerator;

public class OpenPGP {

    PGPPublicKey publicKey;

    PGPPublicKeyRing keyRing;

    public PGPPublicKey getPublicKeyFromString(String data) {
        InputStream input = new ByteArrayInputStream(data.getBytes());
        try {
            PGPPublicKeyRingCollection pgpPub = new PGPPublicKeyRingCollection(PGPUtil.getDecoderStream(input),
                    new JcaKeyFingerprintCalculator());

            Iterator keyRingIter = pgpPub.getKeyRings();
            while (keyRingIter.hasNext()) {
                PGPPublicKeyRing keyRing = (PGPPublicKeyRing) keyRingIter.next();

                Iterator keyIter = keyRing.getPublicKeys();
                while (keyIter.hasNext()) {
                    PGPPublicKey key = (PGPPublicKey) keyIter.next();
                    if (key.isEncryptionKey()) {
                        return key;
                    }
                }
            }

            throw new IllegalArgumentException("Can't find encryption key in key ring.");
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (PGPException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
    }

    public OpenPGP(String publicKey) {
        this.publicKey = getPublicKeyFromString(publicKey);
    }

    static byte[] compressFile(byte[] data, int algorithm) throws IOException {
        byte[] buffer = new byte[4096];
        ByteArrayOutputStream bOut = new ByteArrayOutputStream();
        PGPCompressedDataGenerator comData = new PGPCompressedDataGenerator(algorithm);
        PGPLiteralDataGenerator lData = new PGPLiteralDataGenerator();
        OutputStream pOut = lData.open(comData.open(bOut), PGPLiteralData.BINARY, "fancyfile", new Date(), buffer);

        //        PGPUtil.writeFileToLiteralData(comData.open(bOut), PGPLiteralData.BINARY,
        //            data);
        pOut.write(data);
        pOut.close();
        comData.close();
        return bOut.toByteArray();
    }

    public String getEncryptedMessage(byte[] data) {
        Security.addProvider(new BouncyCastleProvider());

        try {

            ByteArrayOutputStream baos = new ByteArrayOutputStream();

            OutputStream out = new ArmoredOutputStream(baos);
            byte[] compressedData = compressFile(data, CompressionAlgorithmTags.ZIP);
            PGPEncryptedDataGenerator encGen = new PGPEncryptedDataGenerator(
                    new JcePGPDataEncryptorBuilder(PGPEncryptedData.AES_128).setWithIntegrityPacket(true)
                            .setSecureRandom(new SecureRandom()).setProvider("BC"));

            encGen.addMethod(new JcePublicKeyKeyEncryptionMethodGenerator(this.publicKey).setProvider("BC"));
            OutputStream cOut = encGen.open(out, compressedData.length);
            cOut.write(compressedData);
            cOut.close();
            out.close();
            baos.flush();
            return new String(baos.toByteArray());
        } catch (PGPException | IOException e) {
            e.printStackTrace();
        }
        return null;
    }
}