All Downloads are FREE. Search and download functionalities are using the official Maven repository.

dorkbox.util.crypto.CryptoPGP Maven / Gradle / Ivy

There is a newer version: 1.48
Show newest version
/*
 * Copyright 2015 dorkbox, llc
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package dorkbox.util.crypto;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.security.NoSuchProviderException;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.bouncycastle.bcpg.ArmoredOutputStream;
import org.bouncycastle.bcpg.BCPGOutputStream;
import org.bouncycastle.bcpg.CompressionAlgorithmTags;
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.PGPObjectFactory;
import org.bouncycastle.openpgp.PGPPublicKey;
import org.bouncycastle.openpgp.PGPPublicKeyRing;
import org.bouncycastle.openpgp.PGPPublicKeyRingCollection;
import org.bouncycastle.openpgp.PGPSecretKey;
import org.bouncycastle.openpgp.PGPSecretKeyRing;
import org.bouncycastle.openpgp.PGPSecretKeyRingCollection;
import org.bouncycastle.openpgp.PGPSignature;
import org.bouncycastle.openpgp.PGPSignatureGenerator;
import org.bouncycastle.openpgp.PGPSignatureList;
import org.bouncycastle.openpgp.PGPSignatureSubpacketGenerator;
import org.bouncycastle.openpgp.PGPUtil;
import org.bouncycastle.openpgp.operator.PBESecretKeyDecryptor;
import org.bouncycastle.openpgp.operator.bc.BcKeyFingerprintCalculator;
import org.bouncycastle.openpgp.operator.bc.BcPBESecretKeyDecryptorBuilder;
import org.bouncycastle.openpgp.operator.bc.BcPGPContentSignerBuilder;
import org.bouncycastle.openpgp.operator.bc.BcPGPDataEncryptorBuilder;
import org.bouncycastle.openpgp.operator.bc.BcPGPDigestCalculatorProvider;
import org.bouncycastle.openpgp.operator.bc.BcPublicKeyKeyEncryptionMethodGenerator;

import dorkbox.util.IO;

/**
 * PGP crypto related methods
 */
public final
class CryptoPGP {
    private static final BcPGPDigestCalculatorProvider digestCalculatorProvider = new BcPGPDigestCalculatorProvider();
    private static final BcKeyFingerprintCalculator fingerprintCalculator = new BcKeyFingerprintCalculator();


//    https://github.com/weiliatgithub/bouncycastle-gpg-exampleC
//    https://gist.github.com/turingbirds/3df43f1920a98010667a
//    http://sloanseaman.com/wordpress/2012/05/13/revisited-pgp-encryptiondecryption-in-java/
//    http://bouncycastle-pgp-cookbook.blogspot.de/

    /**
     * Sign a message using our private PGP key file, this matches gpg -ab "hello.txt"
     *
     * @param privateKeyInputStream
     *                 this is an armored key file, not a binary stream
     * @param userId
     *                 this is the userID to get out of the private key
     * @param password
     *                 this is the password to unlock the private key
     * @param messageAsUtf8Bytes
     *                 this is the message, in bytes, to sign
     */
    public static
    byte[] signGpgCompatible(InputStream privateKeyInputStream, String userId, char[] password, byte[] messageAsUtf8Bytes)
                    throws PGPException {

        // the signature type (in gpg terms), is "sigclass". gpg is BINARY_DOC (0x00)
        return sign(privateKeyInputStream,
                    userId,
                    password,
                    new ByteArrayInputStream(messageAsUtf8Bytes),
                    PGPSignature.BINARY_DOCUMENT,
                    false,
                    true,
                    false,
                    false,
                    false);
    }

    /**
     * Sign a message using our private PGP key file, this matches gpg -ab "hello.txt"
     *
     * @param privateKeyInputStream
     *                 this is an armored key file, not a binary stream
     * @param userId
     *                 this is the userID to get out of the private key
     * @param password
     *                 this is the password to unlock the private key
     * @param message
     *                 this is the message to sign
     */
    public static
    byte[] signGpgCompatible(InputStream privateKeyInputStream, String userId, char[] password, InputStream message)
                    throws PGPException {

        // the signature type (in gpg terms), is "sigclass". gpg is BINARY_DOC (0x00)
        return sign(privateKeyInputStream,
                    userId,
                    password,
                    message,
                    PGPSignature.BINARY_DOCUMENT,
                    false,
                    true,
                    false,
                    false,
                    false);
    }

    /**
     * Sign a message using our private PGP key file, this matches gpg -ab "hello.txt". This will save the signature of the passed-in
     * file to file name + .asc
     *
     * @param privateKeyInputStream
     *                 this is an armored key file, not a binary stream
     * @param userId
     *                 this is the userID to get out of the private key
     * @param password
     *                 this is the password to unlock the private key
     * @param file
     *                 this is the file to sign
     */
    public static
    void signGpgCompatible(InputStream privateKeyInputStream, String userId, char[] password, File file)
                    throws PGPException {

        // the signature type (in gpg terms), is "sigclass". gpg is BINARY_DOC (0x00)
        final byte[] sign = sign(privateKeyInputStream,
                                 userId,
                                 password,
                                 file,
                                 PGPSignature.BINARY_DOCUMENT,
                                 false,
                                 true,
                                 false,
                                 false,
                                 false);

        FileOutputStream fileOutputStream1 = null;
        try {
            fileOutputStream1 = new FileOutputStream(new File(file.getAbsolutePath() + ".asc"));
            fileOutputStream1.write(sign);
            fileOutputStream1.flush();
        } catch (FileNotFoundException e) {
            throw new PGPException("Unable to save signature to file " + file.getAbsolutePath() + ".asc", e);
        } catch (IOException e) {
            throw new PGPException("Unable to save signature to file " + file.getAbsolutePath() + ".asc", e);
        } finally {
            IO.close(fileOutputStream1);
        }
    }

    /**
     * Sign a message using our private PGP key file, with a variety of options
     */
    @SuppressWarnings("Duplicates")
    public static
    byte[] sign(InputStream privateKeyInputStream,
                String userId,
                char[] password,
                InputStream message,
                int signatureType,
                boolean compressSignature,
                boolean asciiArmoredOutput,
                boolean includeDataInSignature,
                boolean generateUserIdSubPacket,
                boolean generateOnePassVersion) throws PGPException {

        List secretKeys = getSecretKeys(privateKeyInputStream, userId);
        PGPSignatureGenerator signature = createSignature(secretKeys, password, signatureType, generateUserIdSubPacket);

        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        OutputStream outputStream = byteArrayOutputStream;
        if (asciiArmoredOutput) {
            outputStream = new ArmoredOutputStream(byteArrayOutputStream);
        }

        PGPCompressedDataGenerator compressedDataGenerator = null;
        BCPGOutputStream bcOutputStream;

        if (compressSignature) {
            compressedDataGenerator = new PGPCompressedDataGenerator(PGPCompressedData.ZLIB);
            try {
                bcOutputStream = new BCPGOutputStream(compressedDataGenerator.open(outputStream));
            } catch (IOException e) {
                throw new PGPException("Unable to open compression stream in the signature", e);
            }
        }
        else {
            bcOutputStream = new BCPGOutputStream(outputStream);
        }

        if (generateOnePassVersion) {
            try {
                signature.generateOnePassVersion(false)
                         .encode(bcOutputStream);
            } catch (IOException e) {
                throw new PGPException("Unable to generate OnePass signature header", e);
            }
        }

        PGPLiteralDataGenerator literalDataGenerator = null;
        OutputStream literalDataOutput = null;

        if (includeDataInSignature) {
            literalDataGenerator = new PGPLiteralDataGenerator();
            try {
                literalDataOutput = literalDataGenerator.open(bcOutputStream,
                                                              PGPLiteralData.BINARY,
                                                              "_CONSOLE",
                                                              message.available(),
                                                              new Date());
            } catch (IOException e1) {
                throw new PGPException("Unable to generate Literal Data signature header", e1);
            }
        }

        try {
            byte[] buffer = new byte[4096];
            int read;

            // update bytes in the streams
            if (literalDataOutput != null) {
                while ((read = message.read(buffer)) > 0) {
                    literalDataOutput.write(buffer, 0, read);
                    signature.update(buffer, 0, read);
                }
                literalDataOutput.flush();
            } else {

                while ((read = message.read(buffer)) > 0) {
                    signature.update(buffer, 0, read);
                }
            }

            // close generators and update signature
            if (literalDataGenerator != null) {
                literalDataGenerator.close();
            }

            signature.generate()
                     .encode(bcOutputStream);


            if (compressedDataGenerator != null) {
                compressedDataGenerator.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            IO.close(bcOutputStream);
            IO.close(outputStream);
            IO.close(literalDataOutput);
        }

        return byteArrayOutputStream.toByteArray();
    }

    /**
     * Sign a message using our private PGP key file, with a variety of options
     */
    @SuppressWarnings("Duplicates")
    public static
    byte[] sign(InputStream privateKeyInputStream,
                String userId,
                char[] password,
                File fileMessage,
                int signatureType,
                boolean compressSignature,
                boolean asciiArmoredOutput,
                boolean includeDataInSignature,
                boolean generateUserIdSubPacket,
                boolean generateOnePassVersion) throws PGPException {

        List secretKeys = getSecretKeys(privateKeyInputStream, userId);
        PGPSignatureGenerator signature = createSignature(secretKeys, password, signatureType, generateUserIdSubPacket);

        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        OutputStream outputStream = byteArrayOutputStream;
        if (asciiArmoredOutput) {
            outputStream = new ArmoredOutputStream(byteArrayOutputStream);
        }

        PGPCompressedDataGenerator compressedDataGenerator = null;
        BCPGOutputStream bcOutputStream;

        if (compressSignature) {
            compressedDataGenerator = new PGPCompressedDataGenerator(PGPCompressedData.ZLIB);
            try {
                bcOutputStream = new BCPGOutputStream(compressedDataGenerator.open(outputStream));
            } catch (IOException e) {
                throw new PGPException("Unable to open compression stream in the signature", e);
            }
        }
        else {
            bcOutputStream = new BCPGOutputStream(outputStream);
        }

        if (generateOnePassVersion) {
            try {
                signature.generateOnePassVersion(false)
                         .encode(bcOutputStream);
            } catch (IOException e) {
                throw new PGPException("Unable to generate OnePass signature header", e);
            }
        }

        PGPLiteralDataGenerator literalDataGenerator = null;
        OutputStream literalDataOutput = null;

        if (includeDataInSignature) {
            literalDataGenerator = new PGPLiteralDataGenerator();
            try {
                literalDataOutput = literalDataGenerator.open(bcOutputStream,
                                                              PGPLiteralData.BINARY,
                                                              fileMessage);
            } catch (IOException e1) {
                throw new PGPException("Unable to generate Literal Data signature header", e1);
            }
        }

        try {
            final FileInputStream fileInputStream = new FileInputStream(fileMessage);

            byte[] buffer = new byte[4096];
            int read;

            // update bytes in the streams
            if (literalDataOutput != null) {
                while ((read = fileInputStream.read(buffer)) > 0) {
                    literalDataOutput.write(buffer, 0, read);
                    signature.update(buffer, 0, read);
                }
                literalDataOutput.flush();
            } else {

                while ((read = fileInputStream.read(buffer)) > 0) {
                    signature.update(buffer, 0, read);
                }
            }

            // close generators and update signature
            if (literalDataGenerator != null) {
                literalDataGenerator.close();
            }

            signature.generate()
                     .encode(bcOutputStream);


            if (compressedDataGenerator != null) {
                compressedDataGenerator.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            IO.close(bcOutputStream);
            IO.close(outputStream);
            IO.close(literalDataOutput);
        }

        return byteArrayOutputStream.toByteArray();
    }


    /**
     * Find private gpg key in InputStream, also closes the input stream
     *
     * @param inputStream
     *                 the inputStream that contains the private (secret) key
     * @param userId
     *                 the user id
     *
     * @return the PGP secret key
     */
    public static
    List getSecretKeys(InputStream inputStream, String userId) throws PGPException {
        // iterate over every private key in the key ring
        PGPSecretKeyRingCollection secretKeyRings;
        try {
            secretKeyRings = new PGPSecretKeyRingCollection(PGPUtil.getDecoderStream(inputStream), fingerprintCalculator);
        } catch (IOException e) {
            throw new PGPException("No private key found in stream!", e);
        } finally {
            IO.close(inputStream);
        }

        // look for the key ring that is used to authenticate our reporting facilities
        Iterator secretKeys = secretKeyRings.getKeyRings(userId);
        List pgpSecretKeys = new ArrayList();

        // iterate over every private key in the ring
        while (secretKeys.hasNext()) {
            PGPSecretKeyRing secretKeyRing = secretKeys.next();
            PGPSecretKey tmpKey = secretKeyRing.getSecretKey();

            if (tmpKey != null) {
                pgpSecretKeys.add(tmpKey);
            }
        }

        if (!pgpSecretKeys.isEmpty()) {
            return pgpSecretKeys;
        }

        throw new PGPException("No private key found in stream!");
    }

    /**
     * Creates the signature that will be used to PGP sign data
     *
     * @param secretKeys
     *                 these are the secret keys
     * @param password
     *                 this is the password to unlock the secret key
     *
     * @return the signature used to sign data
     *
     * @throws PGPException
     */
    private static
    PGPSignatureGenerator createSignature(List secretKeys,
                                          char[] password,
                                          int signatureType,
                                          boolean generateUserIdSubPacket) throws PGPException {

        PGPSecretKey secretKey = null;
        for (int i = 0; i < secretKeys.size(); i++) {
            secretKey = secretKeys.get(i);

            // we ONLY want the signing master key
            if (!secretKey.isSigningKey() || !secretKey.isMasterKey()) {
                secretKey = null;
            }
        }

        if (secretKey == null) {
            throw new PGPException("Secret key is not the signing master key");
        }

//            System.err.println("Signing key = " + tmpKey.isSigningKey() +", Master key = " + tmpKey.isMasterKey() + ", UserId = " +
//                               userId );

        if (password == null) {
            password = new char[0];
        }

        PBESecretKeyDecryptor build = new BcPBESecretKeyDecryptorBuilder(digestCalculatorProvider).build(password);

        SecureRandom random = new SecureRandom();
        BcPGPContentSignerBuilder bcPGPContentSignerBuilder = new BcPGPContentSignerBuilder(secretKey.getPublicKey()
                                                                                                     .getAlgorithm(),
                                                                                            PGPUtil.SHA1).setSecureRandom(random);

        PGPSignatureGenerator signature = new PGPSignatureGenerator(bcPGPContentSignerBuilder);
        signature.init(signatureType, secretKey.extractPrivateKey(build));

        Iterator userIds = secretKey.getPublicKey()
                                    .getUserIDs();

        // use the first userId that matches
        if (userIds.hasNext()) {
            if (generateUserIdSubPacket) {
                PGPSignatureSubpacketGenerator subpacketGenerator = new PGPSignatureSubpacketGenerator();
                subpacketGenerator.addSignerUserID(false, (String) userIds.next());
                signature.setHashedSubpackets(subpacketGenerator.generate());
            }
            else {
                signature.setHashedSubpackets(null);
            }

            return signature;
        }
        else {
            throw new PGPException("Did not find specified userId");
        }
    }










    /**
     * Decode a PGP public key block and return the keyring it represents.
     */
    public static
    PGPPublicKeyRing getKeyring(InputStream keyBlockStream) throws IOException {

        BcKeyFingerprintCalculator keyfp = new BcKeyFingerprintCalculator();

        // PGPUtil.getDecoderStream() will detect ASCII-armor automatically and decode it,
        // the PGPObject factory then knows how to read all the data in the encoded stream
        PGPObjectFactory factory = new PGPObjectFactory(PGPUtil.getDecoderStream(keyBlockStream), keyfp);

        // these files should really just have one object in them, and that object should be a PGPPublicKeyRing.
        Object o = factory.nextObject();
        if (o instanceof PGPPublicKeyRing) {
            return (PGPPublicKeyRing) o;
        }
        throw new IllegalArgumentException("Input stream does not contain a PGP Public Key");
    }

    /**
     * Get the first encryption key from the given keyring.
     */
    public static
    PGPPublicKey getEncryptionKey(PGPPublicKeyRing keyRing) {
        if (keyRing == null) {
            return null;
        }

        // iterate over the keys on the ring, look for one which is suitable for encryption.
        Iterator keys = keyRing.getPublicKeys();
        PGPPublicKey key;
        while (keys.hasNext()) {
            key = (PGPPublicKey) keys.next();
            if (key.isEncryptionKey()) {
                return key;
            }
        }

        return null;
    }

    /**
     * Get the first decryption key from the given keyring.
     */
    public
    PGPSecretKey getDecryptionKey(PGPSecretKeyRing keyRing) {
        if (keyRing == null) {
            return null;
        }

        // iterate over the keys on the ring, look for one which is suitable for encryption.
        Iterator keys = keyRing.getSecretKeys();
        PGPSecretKey key;
        while (keys.hasNext()) {
            key = (PGPSecretKey) keys.next();
            if (key.isMasterKey()) {
                return key;
            }
        }

        return null;
    }


    /**
     * Encrypt plaintext message using public key from publickeyFile.
     *
     * @param message
     *                 the message
     *
     * @return the string
     */
    private
    String encrypt(InputStream publicKeyInputStream, String message) throws PGPException, IOException, NoSuchProviderException {
        // find the PGP key in the file
        PGPPublicKey publicKey = findPublicGPGKey(publicKeyInputStream);

        if (publicKey == null) {
            System.err.println("Did not find public GPG key");
            return null;
        }


        // Encode the string into bytes using utf-8
        byte[] utf8Bytes = message.getBytes(StandardCharsets.UTF_8);

        ByteArrayOutputStream compressedOutput = new ByteArrayOutputStream();

        // compress bytes with zip
        PGPLiteralDataGenerator literalDataGenerator = new PGPLiteralDataGenerator();

        // the reason why we compress here is GPG not being able to decrypt our message input but if we do not compress.
        // I guess pkzip compression also encodes only to GPG-friendly characters.
        PGPCompressedDataGenerator compressedDataGenerator = new PGPCompressedDataGenerator(CompressionAlgorithmTags.ZIP);
        try {
            OutputStream literalDataOutput = literalDataGenerator.open(compressedOutput,
                                                                       PGPLiteralData.BINARY,
                                                                       "_CONSOLE",
                                                                       utf8Bytes.length,
                                                                       new Date());
            // update bytes in the stream
            literalDataOutput.write(utf8Bytes);
        } catch (IOException e) {
            // catch but close the streams in finally
            throw e;
        } finally {
            compressedDataGenerator.close();
            IO.close(compressedOutput);
        }

        SecureRandom random = new SecureRandom();

        // now we have zip-compressed bytes
        byte[] compressedBytes = compressedOutput.toByteArray();

        BcPGPDataEncryptorBuilder bcPGPDataEncryptorBuilder = new BcPGPDataEncryptorBuilder(PGPEncryptedData.CAST5)
                        .setWithIntegrityPacket(true)
                        .setSecureRandom(random);

        PGPEncryptedDataGenerator encryptedDataGenerator = new PGPEncryptedDataGenerator(bcPGPDataEncryptorBuilder);

        // use public key to encrypt data

        BcPublicKeyKeyEncryptionMethodGenerator encKeyGen = new BcPublicKeyKeyEncryptionMethodGenerator(publicKey)
                        .setSecureRandom(random);

        encryptedDataGenerator.addMethod(encKeyGen);

        // literalDataOutput --> compressedOutput --> ArmoredOutputStream --> ByteArrayOutputStream
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        ArmoredOutputStream armoredOut = new ArmoredOutputStream(byteArrayOutputStream);
        OutputStream encryptedOutput = null;
        try {
            encryptedOutput = encryptedDataGenerator.open(armoredOut, compressedBytes.length);
            encryptedOutput.write(compressedBytes);
        } catch (IOException e) {
            throw e;
        } catch (PGPException e) {
            throw e;
        } finally {
            IO.close(encryptedOutput);
            IO.close(armoredOut);
        }
        String encrypted = new String(byteArrayOutputStream.toByteArray());

        System.err.println("Message: " + message);
        System.err.println("Encrypted: " + encrypted);

        return encrypted;
    }

    /**
     * Find public gpg key in InputStream.
     *
     * @param inputStream
     *                 the input stream
     *
     * @return the PGP public key
     */
    private static
    PGPPublicKey findPublicGPGKey(InputStream inputStream) throws IOException, PGPException {

        // get all key rings in the input stream
        PGPPublicKeyRingCollection publicKeyRingCollection = new PGPPublicKeyRingCollection(PGPUtil.getDecoderStream(inputStream), fingerprintCalculator);

        System.err.println("key ring size: " + publicKeyRingCollection.size());

        Iterator keyRingIter = publicKeyRingCollection.getKeyRings();

        // iterate over keyrings
        while (keyRingIter.hasNext()) {
            PGPPublicKeyRing keyRing = keyRingIter.next();
            Iterator keyIter = keyRing.getPublicKeys();
            // iterate over public keys in the key ring
            while (keyIter.hasNext()) {
                PGPPublicKey tmpKey = keyIter.next();

                if (tmpKey == null) {
                    break;
                }

                Iterator userIDs = tmpKey.getUserIDs();
                ArrayList strings = new ArrayList();
                while (userIDs.hasNext()) {
                    String next = userIDs.next();
                    strings.add(next);
                }

                System.err.println(
                                "Encryption key = " + tmpKey.isEncryptionKey() + ", Master key = " + tmpKey.isMasterKey() + ", UserId = " +
                                strings);

                // we need a master encryption key
                if (tmpKey.isEncryptionKey() && tmpKey.isMasterKey()) {
                    return tmpKey;
                }
            }
        }
        throw new PGPException("No public key found!");
    }



    private static
    void verify(final InputStream publicKeyInputStream, final byte[] signature) throws Exception {
        PGPPublicKey publicKey = findPublicGPGKey(publicKeyInputStream);

        String text = new String(signature);

        Pattern regex = Pattern.compile(
                        "-----BEGIN PGP SIGNED MESSAGE-----\\r?\\n.*?\\r?\\n\\r?\\n(.*)\\r?\\n(-----BEGIN PGP SIGNATURE-----\\r?\\n.*-----END PGP SIGNATURE-----)",
                        Pattern.CANON_EQ | Pattern.DOTALL);
        Matcher regexMatcher = regex.matcher(text);
        if (regexMatcher.find()) {
            String dataText = regexMatcher.group(1);
            String signText = regexMatcher.group(2);

            ByteArrayInputStream dataIn = new ByteArrayInputStream(dataText.getBytes("UTF8"));
            ByteArrayInputStream signIn = new ByteArrayInputStream(signText.getBytes("UTF8"));


            InputStream signIn2 = PGPUtil.getDecoderStream(signIn);

            PGPObjectFactory pgpFact = new PGPObjectFactory(signIn2, new BcKeyFingerprintCalculator());
            PGPSignatureList p3 = null;

            Object o;

            try {
                o = pgpFact.nextObject();
                if (o == null) {
                    throw new Exception();
                }
            } catch (Exception ex) {
                throw new Exception("Invalid input data");
            }

            if (o instanceof PGPCompressedData) {
                PGPCompressedData c1 = (PGPCompressedData) o;

                pgpFact = new PGPObjectFactory(c1.getDataStream(), new BcKeyFingerprintCalculator());

                p3 = (PGPSignatureList) pgpFact.nextObject();
            }
            else {
                p3 = (PGPSignatureList) o;
            }


//            PGPSignature sig = p3.get(0);
//            PGPPublicKey key = KeyRing.getPublicKeyByID(sig.getKeyID());
//
//            if (key == null)
//                throw new Exception("Cannot find key 0x" + Integer.toHexString((int) sig.getKeyID()).toUpperCase() + " in the pubring");
//
//            sig.initVerify(key, "BC");
//
//            while ((ch = dataIn.read()) >= 0) {
//                sig.update((byte) ch); //TODO migliorabile con byte[]
//            }
//
//            if (sig.verify())
//                return new PrintablePGPPublicKey(key).toString();
//            else
//                return null;

//            return verifyFile(dataIn, signIn);

        }
    }


    private
    CryptoPGP() {
    }

    public static
    void main(String[] args) throws Exception {
        InputStream privateKeyInputStream = new FileInputStream(new File("/home/user/dorkbox/sonatype_private.key"));

        byte[] textBytes = "hello".getBytes(StandardCharsets.UTF_8);

        byte[] bytes = CryptoPGP.signGpgCompatible(privateKeyInputStream, "Dorkbox ", new char[0], textBytes);

//        String s = new String(hello);
//        String s1 = s.replaceAll("\n", "\r\n");
//        byte[] bytes = s1.getBytes(OS.UTF_8);

//
//        String signed = new String(bytes);
//
//        System.err.println("Message: " + new String(messageAsUtf8Bytes));
//        System.err.println("Signature: " + signed);
//
//        return bytes;

//        String s2 = new String(bytes);


//        InputStream publicKeyInputStream = new FileInputStream(new File("/home/user/dorkbox/sonatype_public.key"));
//        cryptoPGP.verify(publicKeyInputStream, hello);


        FileOutputStream fileOutputStream = new FileOutputStream(new File("/home/user/dorkbox/hello2.txt"));
        fileOutputStream.write(textBytes);
        fileOutputStream.flush();
        IO.close(fileOutputStream);


        FileOutputStream fileOutputStream1 = new FileOutputStream(new File("/home/user/dorkbox/hello2.txt.asc"));
        fileOutputStream1.write(bytes);
        fileOutputStream1.flush();
        IO.close(fileOutputStream1);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy