13

I am trying to encrypt file using gpg encryption before sending it in my jruby project. However I did not find adequate resources for it. I tried using ruby-gpgme but jruby did not support C libraries. I tried reading Bouncy Castle but I was overwhelmed by the class documentation and did not find a simple article for encrypting a file.

Vivek's answern in this question comes close to my solution, but there is only solution for decrypting the file. I am currently following this article and trying to interface the java code in jruby to no avail. I think the encryptFile function is what I need which is as follows:

public static void encryptFile(
        OutputStream out,
        String fileName,
        PGPPublicKey encKey,
        boolean armor,
        boolean withIntegrityCheck)
        throws IOException, NoSuchProviderException, PGPException
    {
        Security.addProvider(new BouncyCastleProvider());

        if (armor) {
            out = new ArmoredOutputStream(out);
        }

        ByteArrayOutputStream bOut = new ByteArrayOutputStream();
        PGPCompressedDataGenerator comData = new PGPCompressedDataGenerator(PGPCompressedData.ZIP);

        PGPUtil.writeFileToLiteralData(
                comData.open(bOut),
                PGPLiteralData.BINARY,
                new File(fileName) );

        comData.close();

        BcPGPDataEncryptorBuilder dataEncryptor = new BcPGPDataEncryptorBuilder(PGPEncryptedData.TRIPLE_DES);
        dataEncryptor.setWithIntegrityPacket(withIntegrityCheck);
        dataEncryptor.setSecureRandom(new SecureRandom());

        PGPEncryptedDataGenerator encryptedDataGenerator = new PGPEncryptedDataGenerator(dataEncryptor);
        encryptedDataGenerator.addMethod(new BcPublicKeyKeyEncryptionMethodGenerator(encKey));

        byte[] bytes = bOut.toByteArray();
        OutputStream cOut = encryptedDataGenerator.open(out, bytes.length);
        cOut.write(bytes);
        cOut.close();
        out.close();
    }

)

I am getting following error:

NoMethodError: undefined method `ZIP' for Java::OrgBouncycastleOpenpgp::PGPCompressedData:Class

at

 PGPCompressedDataGenerator comData = new PGPCompressedDataGenerator(PGPCompressedData.ZIP);

It would be a great help if you can help me with the code or with the encrypting file using gpg in jruby as a whole.

Update 1 The ZIP value turns out to be constant of integer value and is listed in this page.

Update 2 I made it till the function:

PGPEncryptedDataGenerator encryptedDataGenerator = new PGPEncryptedDataGenerator(dataEncryptor);
    encryptedDataGenerator.addMethod(new BcPublicKeyKeyEncryptionMethodGenerator(encKey)); // encKey is class PGPPublicKey's instance

I have public key generated from OS. How do I create a PGPPublic Key instance encKeyfrom the public key string I have?

Pravin
  • 1,671
  • 5
  • 23
  • 36
  • `ZIP` may be a class constant rather than a method. try using `PGPCompressedData::ZIP` to reference a class constant rather than a `.ZIP` to reference a class method. – EnabrenTane Nov 28 '16 at 06:25
  • yeah, I found the respective constant value of the zip from this page. https://www.bouncycastle.org/docs/pgdocs1.5on/constant-values.html#org.bouncycastle.openpgp.PGPLiteralData.BINARY – Pravin Nov 28 '16 at 06:44
  • i'm still trying to write a wrapper around it just for the encryption. help would be really appreciated. – Pravin Nov 28 '16 at 06:44
  • Yeah, in Ruby `PGPCompressedData.zip` would call a method. You want to reference a constant inside the class. Using `::` rather than `.` should do the trick. Reflecting on `PGPCompressedData` with `PGPCompressedData.constants.sort` and `PGPCompressedData.methods.sort` may also help. Replacing `PGPCompressedData.ZIP` with `PGPCompressedData::ZIP` should do it if it is a constant. – EnabrenTane Nov 28 '16 at 06:52
  • @EnabrenTane I just passed the integer value. – Pravin Nov 28 '16 at 07:33

1 Answers1

0

I could not find enough answer or gem to do it including the pgp library in the project folder. So I have forked this repo to this repo to interface rails and the system's gpg library. It works on ubuntu. I have not tested it on other machines.

Encryption:

In the machine with the public key installed

encryptObj = Gpgr::Encrypt::GpgFileForEncryption.new
encryptObj.email_address = <email_of_gpg_owner>
encryptObj.file = <path_to_file_to_encrypt>
encryptObj.file_output = <path_to_output_file>
encryptObj.encrypt

Decryption

In the machine with the private key

decryptObj = Gpgr::Decrypt::GpgFileForDecryption.new
decryptObj.file = <path_to_file_to_decrypt>
decryptObj.file_output = <path_to_output_file>
decryptObj.decrypt
Pravin
  • 1,671
  • 5
  • 23
  • 36