Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bouncy Castle PGP sign and encrypt in one pass?

I'm looking for an implementation of Bouncy Castle PGP 'sign and encrypt'. Ideally in one operation, if that makes any difference.

I've taken the encrypt example and the signing example and tried to turn it into a 'one pass' encrypt and sign operation.

I see this relatively dated implementation Boncode. It seems to show that the two operations are just linked together.

I'm not getting the consumer to decrypt the code. The signature seems to be able to be verified. This is true whether I use the merged operations or separate encrypt then sign.

Is there a better Bouncy Castle PGP implementation?

like image 507
Interlated Avatar asked Dec 06 '17 23:12

Interlated


People also ask

Can you double encrypt PGP?

Double encryption does not increase the security. There are two modes of using PGP: asymmetric (public key, with a private key to decrypt), and symmetric (with a passphrase). With either mode the message is encrypted with a session key, which is typically a randomly generated 128-bit number.

Is PGP hackable?

Though PGP encryption cannot be hacked, OpenPGP does have a vulnerability that disrupts PGP encrypted messages when exploited. The vulnerability permits public keys stored in Synchronising Key Servers (SKS) to undergo unlimited alterations by cybercriminals.

What is PGP encryption and signing?

Pretty Good Privacy (PGP) is an encryption program that provides cryptographic privacy and authentication for data communication. PGP is used for signing, encrypting, and decrypting texts, e-mails, files, directories, and whole disk partitions and to increase the security of e-mail communications.

Can you encrypt files with PGP?

Use the PGP Encrypt File activity to encrypt files before backing them up. To use this activity, you must install the gpg executable. This activity supports DSS and RSA4 keys.


1 Answers

Here is my current implementation of a one pass, Bouncy Castle PGP encrypt+sign. The signature seems to verify, but the payload is not decrypted.

public class SinglePassSignedEncryptedFileProcessor {
private static final Logger logger = LoggerFactory.getLogger(SinglePassSignedEncryptedFileProcessor.class);

/*
 * This is the primary function that will create encrypt a file and sign it
 * with a one pass signature. This leans on an C# example by John Opincar
 * @author Bilal Soylu
 * @param targetFileName
 *            -- file name on drive systems that will contain encrypted content
 * @param embeddedFileName
 *            -- the original file name before encryption
 * @param secretKeyRingInputStream
 *            -- Private Key Ring File
 * @param targetFileStream
 *            -- The stream for the encrypted target file
 * @param secretKeyPassphrase
 *            -- The private key password for the key retrieved from
 *            collection used for signing
 * @param signPublicKeyInputStream
 *            -- the public key of the target recipient to be used to
 *            encrypt the file
 * @throws Exception
 */
public void encryptOnePassSign(
        String fileName,
        InputStream keyIn,
        OutputStream out,
        char[] pass,
        PGPPublicKey encryptionKey,
        boolean armor,
        boolean withIntegrityCheck,
        String providerName)
        throws IOException, NoSuchAlgorithmException, NoSuchProviderException, PGPException, SignatureException {
    if (armor) {
        out = new ArmoredOutputStream(out);
    }

    // Compress
    byte[] bytes = PGPEncryptUtil.compressFile(fileName, CompressionAlgorithmTags.ZIP);

    // Encryption process.
    PGPEncryptedDataGenerator encGen = new PGPEncryptedDataGenerator(
            new JcePGPDataEncryptorBuilder(PGPEncryptedData.CAST5).setWithIntegrityPacket(withIntegrityCheck).setSecureRandom(new SecureRandom()).setProvider("BC"));

    encGen.addMethod(new JcePublicKeyKeyEncryptionMethodGenerator(encryptionKey).setProvider("BC"));

    ByteArrayOutputStream encryptedOutputStream = new ByteArrayOutputStream();
    OutputStream encryptedOut = encGen.open(encryptedOutputStream, bytes);
    encryptedOut.write(bytes);
    encryptedOut.close();
    byte[] bytesEncrypted = encryptedOutputStream.toByteArray();
    encryptedOutputStream.close();

    // Signing process.
    PGPSecretKey pgpSec = PGPEncryptUtil.readSecretKey(keyIn);
    PGPPrivateKey pgpPrivKey = pgpSec.extractPrivateKey(new JcePBESecretKeyDecryptorBuilder().setProvider("BC").build(pass));

    PGPSignatureGenerator sGen = new PGPSignatureGenerator(new JcaPGPContentSignerBuilder(pgpSec.getPublicKey().getAlgorithm(), PGPUtil.SHA1).setProvider("BC"));

    sGen.init(PGPSignature.BINARY_DOCUMENT, pgpPrivKey);

    Iterator it = pgpSec.getPublicKey().getUserIDs();
    if (it.hasNext()) {
        PGPSignatureSubpacketGenerator spGen = new PGPSignatureSubpacketGenerator();

        spGen.setSignerUserID(false, (String) it.next());
        sGen.setHashedSubpackets(spGen.generate());
    }

    PGPCompressedDataGenerator cGen = new PGPCompressedDataGenerator(
            PGPCompressedData.UNCOMPRESSED);

    // Write to the output stream.
    BCPGOutputStream bOut = new BCPGOutputStream(cGen.open(out));
    sGen.generateOnePassVersion(false).encode(bOut);

    File file = new File(fileName);
    PGPLiteralDataGenerator lGen = new PGPLiteralDataGenerator();
    // file is encoding name.
    Date lastModified = new Date(file.lastModified());
    OutputStream lOut = lGen.open(bOut, PGPLiteralData.BINARY, fileName, lastModified, bytesEncrypted);


    //FileInputStream fIn = new FileInputStream(file);
    //int ch;

    //while ((ch = fIn.read()) >= 0) {
        lOut.write(bytesEncrypted);
        sGen.update(bytesEncrypted);
   // }

    // ?
    lGen.close();

    sGen.generate().encode(bOut);
    cGen.close();

    if (armor) {
        out.close();
    }
    // close everything down we are done
    /*
    literalOut.close();
    literalDataGenerator.close();
    signatureGenerator.generate().encode(compressedOut);
    compressedOut.close();
    compressedDataGenerator.close();
    encryptedOut.close();
    encryptedDataGenerator.close();
     */

    // if (armor) targetFileStream.close();

}
}
like image 63
Interlated Avatar answered Oct 10 '22 20:10

Interlated