Java GPG encode and decode

GPG

  • GPG的生成请参考GPG入门教程
  • 生成gpg的过程中执行下面命令,可以加快生成的速度
    # 随机生成1百万个1K的文件
    cd /tmp
    seq 1000000 | xargs -i dd if=/dev/zero of={}.dat bs=1024 count=1
    

    pom 文件中 bouncycastle dependency

          <dependency>
              <groupId>org.bouncycastle</groupId>
              <artifactId>bcpg-jdk15on</artifactId>
              <version>1.52</version>
          </dependency>
    

GPGUtil.java

  • GPGUtil里面的内容是参考org.bouncycastle.openpgp.examples.PGPExampleUtil 和 org.bouncycastle.openpgp.examples.KeyBasedFileProcessor ``` java package com.wzhonggo.util;

import org.bouncycastle.bcpg.ArmoredOutputStream; import org.bouncycastle.bcpg.CompressionAlgorithmTags; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.openpgp.; import org.bouncycastle.openpgp.jcajce.JcaPGPObjectFactory; import org.bouncycastle.openpgp.operator.jcajce.; import org.bouncycastle.util.io.Streams;

import java.io.*; import java.security.NoSuchProviderException; import java.security.SecureRandom; import java.security.Security; import java.util.Iterator;

/**

  • Created by wzhonggo on 7/14/2017. */ public class GPGUtil { static { try { Security.addProvider(new BouncyCastleProvider()); } catch (Exception e) { e.printStackTrace(); } }

    public static void decryptFile( String inputFileName, String keyFileName, char[] passwd, String defaultFileName) throws IOException, NoSuchProviderException { InputStream in = new BufferedInputStream(new FileInputStream(inputFileName)); InputStream keyIn = new BufferedInputStream(new FileInputStream(keyFileName)); decryptFile(in, keyIn, passwd, defaultFileName); keyIn.close(); in.close(); }

    /**

    • decrypt the passed in message stream */ private static void decryptFile( InputStream in, InputStream keyIn, char[] passwd, String defaultFileName) throws IOException, NoSuchProviderException { in = PGPUtil.getDecoderStream(in);

      try { JcaPGPObjectFactory pgpF = new JcaPGPObjectFactory(in); PGPEncryptedDataList enc;

       Object o = pgpF.nextObject();
       //
       // the first object might be a PGP marker packet.
       //
       if (o instanceof PGPEncryptedDataList) {
           enc = (PGPEncryptedDataList) o;
       } else {
           enc = (PGPEncryptedDataList) pgpF.nextObject();
       }
      
       //
       // find the secret key
       //
       Iterator it = enc.getEncryptedDataObjects();
       PGPPrivateKey sKey = null;
       PGPPublicKeyEncryptedData pbe = null;
       PGPSecretKeyRingCollection pgpSec = new PGPSecretKeyRingCollection(
               PGPUtil.getDecoderStream(keyIn), new JcaKeyFingerprintCalculator());
      
       while (sKey == null && it.hasNext()) {
           pbe = (PGPPublicKeyEncryptedData) it.next();
      
           sKey = findSecretKey(pgpSec, pbe.getKeyID(), passwd);
       }
      
       if (sKey == null) {
           throw new IllegalArgumentException("secret key for message not found.");
       }
      
       InputStream clear = pbe.getDataStream(new JcePublicKeyDataDecryptorFactoryBuilder().setProvider("BC").build(sKey));
      
       JcaPGPObjectFactory plainFact = new JcaPGPObjectFactory(clear);
      
       Object message = plainFact.nextObject();
      
       if (message instanceof PGPCompressedData) {
           PGPCompressedData cData = (PGPCompressedData) message;
           JcaPGPObjectFactory pgpFact = new JcaPGPObjectFactory(cData.getDataStream());
      
           message = pgpFact.nextObject();
       }
      
       if (message instanceof PGPLiteralData) {
           PGPLiteralData ld = (PGPLiteralData) message;
      

// String outFileName = ld.getFileName(); // if (outFileName.length() == 0) { // outFileName = defaultFileName; // } String outFileName = defaultFileName;

            InputStream unc = ld.getInputStream();
            OutputStream fOut = new BufferedOutputStream(new FileOutputStream(outFileName));

            Streams.pipeAll(unc, fOut);

            fOut.close();
        } else if (message instanceof PGPOnePassSignatureList) {
            throw new PGPException("encrypted message contains a signed message - not literal data.");
        } else {
            throw new PGPException("message is not a simple encrypted file - type unknown.");
        }

        if (pbe.isIntegrityProtected()) {
            if (!pbe.verify()) {
                System.err.println("message failed integrity check");
            } else {
                System.err.println("message integrity check passed");
            }
        } else {
            System.err.println("no message integrity check");
        }
    } catch (PGPException e) {
        System.err.println(e);
        if (e.getUnderlyingException() != null) {
            e.getUnderlyingException().printStackTrace();
        }
    }
}


private static byte[] compressFile(String fileName, int algorithm) throws IOException {
    ByteArrayOutputStream bOut = new ByteArrayOutputStream();
    PGPCompressedDataGenerator comData = new PGPCompressedDataGenerator(algorithm);
    PGPUtil.writeFileToLiteralData(comData.open(bOut), PGPLiteralData.BINARY,
            new File(fileName));
    comData.close();
    return bOut.toByteArray();
}


public static void encryptFile(
        String outputFileName,
        String inputFileName,
        String encKeyFileName,
        boolean armor,
        boolean withIntegrityCheck)
        throws IOException, NoSuchProviderException, PGPException {
    OutputStream out = new BufferedOutputStream(new FileOutputStream(outputFileName));
    PGPPublicKey encKey = readPublicKey(encKeyFileName);
    encryptFile(out, inputFileName, encKey, armor, withIntegrityCheck);
    out.close();
}

private static void encryptFile(
        OutputStream out,
        String fileName,
        PGPPublicKey encKey,
        boolean armor,
        boolean withIntegrityCheck)
        throws IOException, NoSuchProviderException {
    if (armor) {
        out = new ArmoredOutputStream(out);
    }

    try {
        byte[] bytes = compressFile(fileName, CompressionAlgorithmTags.ZIP);

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

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

        OutputStream cOut = encGen.open(out, bytes.length);

        cOut.write(bytes);
        cOut.close();

        if (armor) {
            out.close();
        }
    } catch (PGPException e) {
        System.err.println(e);
        if (e.getUnderlyingException() != null) {
            e.getUnderlyingException().printStackTrace();
        }
    }
}


private static PGPPublicKey readPublicKey(String fileName) throws IOException, PGPException {
    InputStream keyIn = new BufferedInputStream(new FileInputStream(fileName));
    PGPPublicKey pubKey = readPublicKey(keyIn);
    keyIn.close();
    return pubKey;
}

private static PGPPublicKey readPublicKey(InputStream input) throws IOException, PGPException {
    PGPPublicKeyRingCollection pgpPub = new PGPPublicKeyRingCollection(
            PGPUtil.getDecoderStream(input), new JcaKeyFingerprintCalculator());

    //
    // we just loop through the collection till we find a key suitable for encryption, in the real
    // world you would probably want to be a bit smarter about this.
    //

    Iterator keyRingIter = pgpPub.getKeyRings();
    while (keyRingIter.hasNext()) {
        PGPPublicKeyRing keyRing = (PGPPublicKeyRing) keyRingIter.next();

        Iterator keyIter = keyRing.getPublicKeys();
        while (keyIter.hasNext()) {
            PGPPublicKey key = (PGPPublicKey) keyIter.next();

            if (key.isEncryptionKey()) {
                return key;
            }
        }
    }

    throw new IllegalArgumentException("Can't find encryption key in key ring.");
}

private static PGPPrivateKey findSecretKey(PGPSecretKeyRingCollection pgpSec, long keyID, char[] pass)
        throws PGPException, NoSuchProviderException {
    PGPSecretKey pgpSecKey = pgpSec.getSecretKey(keyID);

    if (pgpSecKey == null) {
        return null;
    }

    return pgpSecKey.extractPrivateKey(new JcePBESecretKeyDecryptorBuilder().setProvider("BC").build(pass));
} }

# GPGDemo.java
* 替换掉 gpg public key 文件, gpg secret key文件, gpg password, 以及test.xml
* 运行GPGDemo后会发现test_decode.xml中的内容和test.xml中的内容一样
``` java
 package com.wzhonggo.util;

import org.bouncycastle.openpgp.*;
import java.io.*;
import java.security.NoSuchProviderException;

/**
 * Created by wzhonggo on 7/14/2017.
 */
public class GPGDemo {
        public static void main(String [] args) throws NoSuchProviderException, IOException, PGPException {
            String password ="gpgPassword";
            String gpgPublicKey="pubring.gpg"
            String gpgSecretKey="secring.gpg"
            GPGUtil.encryptFile("test_encode.xml", "test.xml", gpgPublicKey, false, false);
            GPGUtil.decryptFile("test_encode.xml",gpgSecretKey, password.toCharArray(), "test_decode.xml");
    }
}

#


参考文档
最近的文章

python monitor ubuntu port

环境 Ubuntu 14.04 Python 2.7 JDK8通过python监控ubuntu上面的端口 通过crontab调用shell脚本, shell脚本里面会根据指定的端口去查找是否能连接上,如果不能连接会先发送消息,然后尝试重启改端口对应的服务,如果重启成功会发送重启成功的消失,失败会发送失败的消失,通过修改javaCmd,让具体消失发送可以是email,也可以是其他的。monitor.sh#!/bin/bashcd /home/ubuntu/SNS/#/home/ubu...…

继续阅读
更早的文章

Restricting IP addresses for Jetty and Solr

环境 Solr6.3.0 (jetty-server-9.3.8.v20160314) Solr6.6.0 (jetty-server-9.3.14.v20161028) Solr默认外网直接可以通过8983端口访问, Solr限制访问的ip为127.0.0.1, 这样外网ip可以访问8983端口,但是api访问,response http code 都是403, jetty xml配置语法参考Jetty IoC XML format Solr6.3.0 修改$solr...…

继续阅读