eu.mrbussy.security.crypto.pgp.PGPEncryptor.java Source code

Java tutorial

Introduction

Here is the source code for eu.mrbussy.security.crypto.pgp.PGPEncryptor.java

Source

/*
 * Java-Password-Store
 * Copyright (C) 2016  rudi
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program 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 General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package eu.mrbussy.security.crypto.pgp;

import org.apache.commons.io.IOUtils;
import org.bouncycastle.bcpg.ArmoredOutputStream;
import org.bouncycastle.openpgp.PGPCompressedData;
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.PGPPrivateKey;
import org.bouncycastle.openpgp.PGPPublicKey;
import org.bouncycastle.openpgp.PGPSecretKey;
import org.bouncycastle.openpgp.PGPSignature;
import org.bouncycastle.openpgp.PGPSignatureGenerator;
import org.bouncycastle.openpgp.PGPSignatureSubpacketGenerator;
import org.bouncycastle.openpgp.PGPUtil;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.SecureRandom;
import java.security.SignatureException;
import java.util.Iterator;

public class PGPEncryptor {

    private boolean isArmored;
    private boolean checkIntegrity;
    private String publicKeyFilePath;
    private PGPPublicKey publicKey;

    private String signingPrivateKeyFilePath;
    private String signingPrivateKeyPassword;

    public String getSigningPrivateKeyPassword() {
        return signingPrivateKeyPassword;
    }

    public void setSigningPrivateKeyPassword(String signingPrivateKeyPassword) {
        this.signingPrivateKeyPassword = signingPrivateKeyPassword;
    }

    public String getSigningPrivateKeyFilePath() {
        return signingPrivateKeyFilePath;
    }

    public void setSigningPrivateKeyFilePath(String signingPrivateKeyFilePath) {
        this.signingPrivateKeyFilePath = signingPrivateKeyFilePath;
    }

    public boolean isSigning() {
        return isSigning;
    }

    public void setSigning(boolean isSigning) {
        this.isSigning = isSigning;
    }

    private boolean isSigning;

    private PGPEncryptedDataGenerator pedg;

    public String getPublicKeyFilePath() {
        return publicKeyFilePath;
    }

    public void setPublicKeyFilePath(String publicKeyFilePath) throws IOException, PGPException {
        this.publicKeyFilePath = publicKeyFilePath;
        publicKey = PGPUtils.readPublicKey(publicKeyFilePath);
    }

    public boolean isArmored() {
        return isArmored;
    }

    public void setArmored(boolean isArmored) {
        this.isArmored = isArmored;
    }

    public boolean isCheckIntegrity() {
        return checkIntegrity;
    }

    public void setCheckIntegrity(boolean checkIntegrity) {
        this.checkIntegrity = checkIntegrity;
    }

    public void encryptFile(String inputFileNamePath, String outputFileNamePath)
            throws IOException, NoSuchProviderException, PGPException {
        encryptFile(new File(inputFileNamePath), new File(outputFileNamePath));
    }

    public void encryptFile(File inputFile, File outputFile)
            throws IOException, NoSuchProviderException, PGPException {
        if (pedg == null) {
            pedg = new PGPEncryptedDataGenerator(PGPEncryptedData.CAST5, checkIntegrity, new SecureRandom(), "BC");

            try {
                pedg.addMethod(publicKey);
            } catch (PGPException e) {
                throw new PGPException("Error when creating PGP encryptino data generator.");
            }
        }
        OutputStream fileOutStream = new FileOutputStream(outputFile);
        if (isArmored) {
            fileOutStream = new ArmoredOutputStream(fileOutStream);
        }

        OutputStream encryptdOutStream = pedg.open(fileOutStream, new byte[1 << 16]);
        PGPCompressedDataGenerator comData = new PGPCompressedDataGenerator(PGPCompressedData.ZIP);
        OutputStream compressedOutStream = comData.open(encryptdOutStream);

        try {
            PGPSignatureGenerator sg = null;
            if (isSigning) {
                InputStream keyInputStream = new FileInputStream(new File(signingPrivateKeyFilePath));
                PGPSecretKey secretKey = PGPUtils.findSecretKey(keyInputStream);
                PGPPrivateKey privateKey = secretKey.extractPrivateKey(signingPrivateKeyPassword.toCharArray(),
                        "BC");
                sg = new PGPSignatureGenerator(secretKey.getPublicKey().getAlgorithm(), PGPUtil.SHA1, "BC");
                sg.initSign(PGPSignature.BINARY_DOCUMENT, privateKey);
                Iterator it = secretKey.getPublicKey().getUserIDs();
                if (it.hasNext()) {
                    PGPSignatureSubpacketGenerator ssg = new PGPSignatureSubpacketGenerator();
                    ssg.setSignerUserID(false, (String) it.next());
                    sg.setHashedSubpackets(ssg.generate());
                }
                sg.generateOnePassVersion(false).encode(compressedOutStream);
            }

            PGPLiteralDataGenerator lg = new PGPLiteralDataGenerator();
            OutputStream literalDataOutStream = lg.open(compressedOutStream, PGPLiteralData.BINARY, inputFile);

            byte[] bytes = IOUtils.toByteArray(new FileInputStream(inputFile));

            literalDataOutStream.write(bytes);
            if (isSigning) {
                sg.update(bytes);
                sg.generate().encode(compressedOutStream);
            }
            literalDataOutStream.close();
            lg.close();
            compressedOutStream.close();
            comData.close();
            pedg.close();
            fileOutStream.close();
        } catch (PGPException e) {
            System.err.println(e);
            if (e.getUnderlyingException() != null) {
                e.getUnderlyingException().printStackTrace();
            }
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (SignatureException e) {
            e.printStackTrace();
        }
    }

}