如何在 jruby9.1.2.0 中使用 PGP 加密对文件进行加密?

Posted

技术标签:

【中文标题】如何在 jruby9.1.2.0 中使用 PGP 加密对文件进行加密?【英文标题】:How to encrypt a file using PGP encryption in jruby9.1.2.0? 【发布时间】:2017-04-09 15:32:05 【问题描述】:

我正在尝试在将文件发送到我的 jruby 项目之前使用 gpg 加密对文件进行加密。但是我没有找到足够的资源。我尝试使用ruby-gpgme,但 jruby 不支持 C 库。我尝试阅读Bouncy Castle,但我被类文档所淹没,并没有找到加密文件的简单文章。

Vivek 在this 问题中的回答接近我的解决方案,但只有解密文件的解决方案。我目前正在关注this article 并尝试在 jruby 中连接 java 代码,但无济于事。我认为encryptFile 函数是我需要的,如下所示:

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();
    

)

我收到以下错误:

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

 PGPCompressedDataGenerator comData = new PGPCompressedDataGenerator(PGPCompressedData.ZIP);

如果您能在代码或整个 jruby 中使用 gpg 加密文件帮助我,那将是一个很大的帮助。

更新 1 ZIP 值原来是整数值的常量,并列在this 页面中。

更新 2 我做到了:

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

我有从操作系统生成的公钥。如何从我拥有的公钥字符串创建 PGPPublic Key 实例encKey

【问题讨论】:

ZIP 可能是类常量而不是方法。尝试使用PGPCompressedData::ZIP 来引用类常量而不是.ZIP 来引用类方法。 是的,我从这个页面找到了相应的 zip 常量值。 bouncycastle.org/docs/pgdocs1.5on/… 我仍在尝试围绕它编写一个包装器,只是为了加密。非常感谢您的帮助。 是的,在 Ruby 中 PGPCompressedData.zip 会调用一个方法。您想在类中引用一个常量。使用:: 而不是. 应该可以解决问题。用PGPCompressedData.constants.sortPGPCompressedData.methods.sort 反思PGPCompressedData 也可能有所帮助。如果 PGPCompressedData.ZIP 是常量,则将 PGPCompressedData.ZIP 替换为 PGPCompressedData::ZIP 应该这样做。 @EnabrenTane 我刚刚传递了整数值。 【参考方案1】:

我找不到足够的答案或 gem 来完成它,包括项目文件夹中的 pgp 库。所以我将this repo 分叉到this repo 以连接rails 和系统的gpg 库。它适用于ubuntu。我没有在其他机器上测试过。

加密:

在安装了公钥的机器上

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

解密

在有私钥的机器上

decryptObj = Gpgr::Decrypt::GpgFileForDecryption.new
decryptObj.file = <path_to_file_to_decrypt>
decryptObj.file_output = <path_to_output_file>
decryptObj.decrypt

【讨论】:

以上是关于如何在 jruby9.1.2.0 中使用 PGP 加密对文件进行加密?的主要内容,如果未能解决你的问题,请参考以下文章

如何利用PGP构建加密磁盘

C# 如何使用 PGP 公钥简单地加密文本文件?

pgp如何打开

如何利用PGP构建加密磁盘

使用 PGP/MIME 签署多部分邮件

现代密码学应用的范例-PGP