Sign and encrypt a file using the OpenPGP way

View: New views
1 Messages — Rating Filter:   Alert me  

Sign and encrypt a file using the OpenPGP way

by Klausi :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hello,

i want to sign and encrypt a file in the same way like OpenPGPs "sign & encrypt" option in WinPT. I tried different scenarios, for example <http://www.nabble.com/Encrypt-THEN-sign-td17470414.html>.
The problem is, that i can decrypt and validate the encrypted and signed file with WinPT. But the couterpart of my application that wants to decrypt and validate the file can't.
I found out, that my encrypted files does not have the same structure like files from OpenPGP.
For the OpenPGP files the PGPObjectFactory returns 2 objects one CompressedData and a LiteralData object. My encrypted file only returns the CompressedData object.

Here a short version of the code:

    private byte[] signAndEncrypt(byte[] inputData) throws Exception
    {
        ByteArrayOutputStream out = new ByteArrayOutputStream();

        OutputStream compressedOut = compressor.open(out);
        onePassSignature.encode(compressedOut);

        PGPLiteralDataGenerator dGen = new PGPLiteralDataGenerator();
        OutputStream dOut = dGen.open(compressedOut, PGPLiteralData.BINARY, "", inputData.length, new Date());
        dOut.write(inputData);
        v4signer.update(inputData);

        dOut.close();
        dGen.close();

        v4signer.generate().encode(compressedOut);
        v4signer.generate().getSignature();
        compressedOut.close();
        compressor.close();
        out.write(v4signer.generate().getSignature());

        byte[] bytes = out.toByteArray();
        ByteArrayOutputStream eOut = new ByteArrayOutputStream();
        OutputStream cOut = encryptor.open(eOut, bytes.length);
        cOut.write(bytes);
        encryptor.close();

        return eOut.toByteArray();
    }

    public static void main(String args[])
    {
        try
        {            
            Security.addProvider(new BouncyCastleProvider());

            String sourceFileName = args[0];
            FileInputStream sourceFile = new FileInputStream(sourceFileName);
            ByteArrayOutputStream bout = new ByteArrayOutputStream();
            int data;
            while ((data = sourceFile.read()) != -1)
            {
                bout.write(data);
            }
            bout.close();
            sourceFile.close();
            byte[] clearData = bout.toByteArray();


            FileInputStream encryptionPublicKey = new FileInputStream(args[1]);
            FileInputStream signPrivateKey = new FileInputStream(args[2]);
            char[] keyPass = args[3].toCharArray();
            String signedFileName = sourceFileName + ".gpg";

            PGPSecretKey secretKey = KeyUtils.readSecretKey(signPrivateKey);
            PGPPublicKey publicKey = KeyUtils.readPublicKey(encryptionPublicKey);

            Variante var = new Variante();
            var.mustArmor = false;
            var.compressor = new PGPCompressedDataGenerator(PGPCompressedData.ZLIB);

            PGPPrivateKey pgpPrivKey = secretKey.extractPrivateKey(keyPass, "BC");
            PGPSignatureGenerator sGen = new PGPSignatureGenerator(secretKey.getPublicKey().getAlgorithm(), PGPUtil.SHA1, "BC");

            sGen.initSign(PGPSignature.BINARY_DOCUMENT, pgpPrivKey);
            Iterator it = secretKey.getPublicKey().getUserIDs();
            if (it.hasNext())
            {
                PGPSignatureSubpacketGenerator spGen = new PGPSignatureSubpacketGenerator();
                spGen.setSignerUserID(false, (String) it.next());
                sGen.setHashedSubpackets(spGen.generate());
            }
            var.v4signer = sGen;
            var.onePassSignature = sGen.generateOnePassVersion(false);

            PGPEncryptedDataGenerator cPk = new PGPEncryptedDataGenerator(PGPEncryptedData.CAST5, true, new SecureRandom(), "BC");
            cPk.addMethod(publicKey);
            var.encryptor = cPk;

            byte[] encryptedData = var.process(clearData);

            // Schreiben der Output-Datei
            ByteArrayInputStream bin = new ByteArrayInputStream(encryptedData);
            FileOutputStream signedOut = new FileOutputStream(signedFileName);
            int signed;
            while ((signed = bin.read()) != -1)
            {
                signedOut.write(signed);
            }
            signedOut.close();
            bin.close();

        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }

any ideas?

regards
Klaus