简体   繁体   English

Java 字符串的 PGP 加密

[英]PGP Encryption of Java String

I have a requirement to encrypt a java string (which is part of a JSON file) using PGP encryption.我需要使用 PGP 加密来加密 java 字符串(它是 JSON 文件的一部分)。 I tried out quite a lot of examples which I could mine out from Google searches.我尝试了很多可以从 Google 搜索中挖掘出的示例。 All of these examples were making use of bouncycastle openpgp methods, which are deprecated.所有这些示例都使用了 bouncycastle openpgp 方法,这些方法已被弃用。 Below is the code I used:下面是我使用的代码:

import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.NoSuchProviderException;
import java.security.SecureRandom;
import java.security.Security;
import org.bouncycastle.bcpg.ArmoredOutputStream;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.openpgp.PGPCompressedDataGenerator;
import org.bouncycastle.openpgp.PGPEncryptedDataGenerator;
import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPLiteralData;
import org.bouncycastle.openpgp.PGPPublicKey;
import org.bouncycastle.openpgp.PGPPublicKeyRing;
import org.bouncycastle.openpgp.PGPUtil;


public class BouncyCastlePGPTest {

    public static void main(String[] args) {

        // the keyring that holds the public key we're encrypting with
        String publicKeyFilePath = "C:\\pgp6.5.8\\pubring.pkr";

        // init the security provider
        Security.addProvider(new BouncyCastleProvider());

        try {

            System.out.println("Creating a temp file...");

            // create a file and write the string to it
            File outputfile = File.createTempFile("pgp", null);
            FileWriter writer = new FileWriter(outputfile);
            writer.write("the message I want to encrypt".toCharArray());
            writer.close();

            System.out.println("Temp file created at ");
            System.out.println(outputfile.getAbsolutePath());
            System.out.println("Reading the temp file to make sure that the bits were written\n----------------------------");

            BufferedReader isr = new BufferedReader(new FileReader(outputfile));
            String line = "";
            while ((line = isr.readLine()) != null) {
                System.out.println(line + "\n");
            }

            // read the key 
            FileInputStream in = new FileInputStream(publicKeyFilePath);
            PGPPublicKey key = readPublicKey(in);

            // find out a little about the keys in the public key ring
            System.out.println("Key Strength = " + key.getBitStrength());
            System.out.println("Algorithm = " + key.getAlgorithm());

            int count = 0;
            for (java.util.Iterator iterator = key.getUserIDs(); iterator.hasNext();) {
                count++;
                System.out.println((String)iterator.next());    
            }
            System.out.println("Key Count = " + count);
            // create an armored ascii file
            FileOutputStream out = new FileOutputStream(outputfile.getAbsolutePath() + ".asc");

            // encrypt the file
            encryptFile(outputfile.getAbsolutePath(), out, key);

            System.out.println("Reading the encrypted file\n----------------------------");
            BufferedReader isr2 = new BufferedReader(new FileReader(new File(outputfile.getAbsolutePath() + ".asc")));
            String line2 = "";
            while ((line2 = isr2.readLine()) != null) {
                System.out.println(line2);
            }



        } catch (PGPException e) {
            System.out.println(e.toString());
            System.out.println(e.getUnderlyingException().toString());

        } catch (Exception e) {
            System.out.println(e.toString());
        }

    }

    private static PGPPublicKey readPublicKey(InputStream in) throws IOException {
        try {
            PGPPublicKeyRing pgpPub = new PGPPublicKeyRing(in);
            return pgpPub.getPublicKey();
        } catch (IOException io) {
            System.out.println("readPublicKey() threw an IOException");
            System.out.println(io.toString());
            throw io;
        }

    }

    private static void encryptFile(String fileName, OutputStream out, PGPPublicKey encKey)
    throws IOException, NoSuchProviderException, PGPException  
    {

        out = new ArmoredOutputStream(out);

        ByteArrayOutputStream bOut = new ByteArrayOutputStream();

        System.out.println("creating comData...");

        // get the data from the original file 
        PGPCompressedDataGenerator comData = new PGPCompressedDataGenerator(PGPCompressedDataGenerator.ZIP);
        PGPUtil.writeFileToLiteralData(comData.open(bOut), PGPLiteralData.BINARY, new File(fileName));
        comData.close();

        System.out.println("comData created...");

        System.out.println("using PGPEncryptedDataGenerator...");

        // object that encrypts the data
        PGPEncryptedDataGenerator cPk = new PGPEncryptedDataGenerator(PGPEncryptedDataGenerator.CAST5, new SecureRandom(), "BC");
        cPk.addMethod(encKey);

        System.out.println("used PGPEncryptedDataGenerator...");

        // take the outputstream of the original file and turn it into a byte array
        byte[] bytes = bOut.toByteArray();

        System.out.println("wrote bOut to byte array...");

        // write the plain text bytes to the armored outputstream
        OutputStream cOut = cPk.open(out, bytes.length);
        cOut.write(bytes);


        // cOut.close();
        cPk.close();
        out.close();


    }

}

Below is a snapshot of my error log:以下是我的错误日志的快照:

BouncyCastlePGPTest.java:96: cannot find symbol                            
symbol  : constructor PGPPublicKeyRing(java.io.InputStream)                
location: class org.bouncycastle.openpgp.PGPPublicKeyRing                  
                        PGPPublicKeyRing pgpPub = new PGPPublicKeyRing(in);
BouncyCastlePGPTest.java:126: cannot find symbol                             
symbol  : constructor PGPEncryptedDataGenerator(int,java.security.SecureRandom,java.lang.String)                                                          
location: class org.bouncycastle.openpgp.PGPEncryptedDataGenerator           
                PGPEncryptedDataGenerator cPk = new PGPEncryptedDataGenerator(PGPEncryptedDataGenerator.CAST5, new SecureRandom(), "BC");                 
                                                ^                            
BouncyCastlePGPTest.java:127: addMethod(org.bouncycastle.openpgp.operator.PGP
KeyEncryptionMethodGenerator) in org.bouncycastle.openpgp.PGPEncryptedDataGen
erator cannot be applied to (org.bouncycastle.openpgp.PGPPublicKey)          
                cPk.addMethod(encKey);                                       
                   ^                    

Can someone point me out to a working sample code which I can use with the latest jars from https://www.bouncycastle.org/latest_releases.html ?有人可以指出我可以与来自https://www.bouncycastle.org/latest_releases.html的最新 jars 一起使用的工作示例代码吗?

Apart from bouncycastle, are there other alternatives?除了bouncycastle,还有其他选择吗? I'm sure it's a very common use case people would come across.我相信这是人们会遇到的一个非常常见的用例。 What is being used these days, if not bouncycastle openpgp?这些天正在使用什么,如果不是 bouncycastle openpgp?

Bouncy Castle is a Java lightweight crypto API and a Java security provider. Bouncy Castle是Java轻量级加密API和Java安全提供程序。 It also provides separate libraries for specific functionality, mainly CMS (Cryptographic Message Syntax) and PGP (Pretty Good Privacy). 它还为特定功能提供了单独的库,主要是CMS(加密消息语法)和PGP(很好的隐私)。

These libraries can be downloaded separately or within the complete crypto- distributions. 这些库可以单独下载,也可以在完整的加密发行版中下载。 They are named bcpkix-jdk15on-159.jar and bcpg-jdk15on-159.jar respectively (for version 1.59). 它们分别被命名为bcpkix-jdk15on-159.jarbcpg-jdk15on-159.jar (对于1.59版)。 You need to include those libraries in your classpath or your Maven setup to perform the compilation. 您需要在类路径或Maven设置中包括这些库以执行编译。

You can actually leave out the Bouncy Castle provider bcprov-... during compilation if your projects do not use the extended API but access everything through the standard Java API. 如果您的项目不使用扩展的API,而是通过标准Java API访问所有内容,则实际上可以在编译过程中 bcprov-... Bouncy Castle 提供程序 bcprov-... However, you can only use the PGP functionality through the PGP API of Bouncy Castle itself, so that won't work for PGP. 但是,您只能通过Bouncy Castle本身的PGP API使用PGP功能,因此不适用于PGP。

I am using the Bouncy Castle list as follows: 我正在使用Bouncy Castle列表,如下所示: 在此处输入图片说明

I have the same exceptions with yours because of the api changing. 由于api更改,我与您有相同的例外。 So, here is complete your sample code. 至此,完成了示例代码。

private static PGPPublicKey readPublicKey(InputStream in) throws IOException {
    try {
        PGPPublicKeyRing pgpPub = new PGPPublicKeyRing(in, new JcaKeyFingerprintCalculator());
        //PGPPublicKeyRing pgpPub = new PGPPublicKeyRing(in);
        return pgpPub.getPublicKey();
    } catch (IOException io) {
        System.out.println("readPublicKey() threw an IOException");
        System.out.println(io.toString());
        throw io;
    }

}

private static void encryptFile(String fileName, OutputStream out, PGPPublicKey encKey)
throws IOException, NoSuchProviderException, PGPException  
{

    out = new ArmoredOutputStream(out);

    ByteArrayOutputStream bOut = new ByteArrayOutputStream();

    System.out.println("creating comData...");

    // get the data from the original file 
    PGPCompressedDataGenerator comData = new PGPCompressedDataGenerator(PGPCompressedDataGenerator.ZIP);
    PGPUtil.writeFileToLiteralData(comData.open(bOut), PGPLiteralData.BINARY, new File(fileName));
    comData.close();

    System.out.println("comData created...");

    System.out.println("using PGPEncryptedDataGenerator...");

    // object that encrypts the data
    //PGPEncryptedDataGenerator cPk = new PGPEncryptedDataGenerator(PGPEncryptedDataGenerator.CAST5, new SecureRandom(), "BC");
    //cPk.addMethod(encKey);
    // object that encrypts the data
    PGPEncryptedDataGenerator cPk = new PGPEncryptedDataGenerator(new JcePGPDataEncryptorBuilder(SymmetricKeyAlgorithmTags.CAST5)
            .setSecureRandom(new SecureRandom()).setProvider("BC"));
    cPk.addMethod(new JcePublicKeyKeyEncryptionMethodGenerator(encKey));

    System.out.println("used PGPEncryptedDataGenerator...");

    // take the outputstream of the original file and turn it into a byte array
    byte[] bytes = bOut.toByteArray();

    System.out.println("wrote bOut to byte array...");

    // write the plain text bytes to the armored outputstream
    OutputStream cOut = cPk.open(out, bytes.length);
    cOut.write(bytes);


    // cOut.close();
    cPk.close();
    out.close();


}

To say about encryption of strings, it depends on your requirement what to do with it. 要说一下字符串加密,这取决于您的要求。 You know that even a base64 encoding might be one option.. 您知道甚至base64编码也可能是一种选择。

You can google or search this site, plenty of them found. 您可以在Google上搜索或搜索该站点,找到了很多。

Have a good coding 编码好

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM