基于JAVA代码进行GPG加解密(代码拿来就可以用)

    银行对接保险公司要对文件进行gpg加密,那保险公司要进行解密了。

    原来想的方案是用java代码编写cmd命令然后执行bat文件,生成指定的文件夹下。这样的话有几个弊端:第一次运行bat文件的时候总是会提示要输入密码,发布到服务器上是不可控的。另一个是服务器是windows系统的话还要安装gpg的软件。

    后来发现java封装有gpg解密的,于是就拿来用了。我的业务逻辑是取指定文件下的以.DAT结尾的gpg加密后的文件,然后遍历生成到制定的文件夹下。

    在这其中遇到了两个坑。

    1、业务逻辑中的方法中一定不要忘记加Security.addProvider(new BouncyCastleProvider());这一句,不然报错,人往往容易一叶障目,这不该发生的问题让我定位了很久才解决。

    2、报这个错误java.security.InvalidKeyException: Illegal key size or default parameters。问题原因是解密的私钥位数太长,跟jdk版本有关系。密钥长度是受限制的, java运行时环境读到的是受限的policy文件. 文件位于${java_home}/jre/lib/security, 这种限制是因为美国对软件出口的控制。在jdk的版本中在jdk1.8的151版本之后就接触了这种限制。当时在本地测试的一切顺利,一发布到测试环境就有问题,后来了解测试环境的jdk版本是jdk1.8的121版本,还是有秘钥长度的限制。相关介绍:https://my.oschina.net/u/1037605/blog/3026103

    首先是maven要引用的jar包。

<dependency>

<groupId>org.bouncycastle</groupId>

<artifactId>bcpg-jdk15on</artifactId>

<version>1.56</version>

</dependency>

下面就是代码了(复制粘贴就可以用了,注意导包,前提你要有相应的秘钥信息)。

import java.io.BufferedInputStream;

import java.io.BufferedOutputStream;

import java.io.File;

import java.io.FileInputStream;

import java.io.FileOutputStream;

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 java.util.ArrayList;

import java.util.Iterator;

import java.util.List;

import com.sinosoft.light.dataswitch.service.util.PGPExampleUtil;

import com.sinosoft.platform.common.exception.SinoSystemException;

import org.bouncycastle.bcpg.ArmoredOutputStream;

import org.bouncycastle.bcpg.CompressionAlgorithmTags;

import org.bouncycastle.jce.provider.BouncyCastleProvider;

import org.bouncycastle.openpgp.PGPCompressedData;

import org.bouncycastle.openpgp.PGPEncryptedData;

import org.bouncycastle.openpgp.PGPEncryptedDataGenerator;

import org.bouncycastle.openpgp.PGPEncryptedDataList;

import org.bouncycastle.openpgp.PGPException;

import org.bouncycastle.openpgp.PGPLiteralData;

import org.bouncycastle.openpgp.PGPOnePassSignatureList;

import org.bouncycastle.openpgp.PGPPrivateKey;

import org.bouncycastle.openpgp.PGPPublicKey;

import org.bouncycastle.openpgp.PGPPublicKeyEncryptedData;

import org.bouncycastle.openpgp.PGPSecretKeyRingCollection;

import org.bouncycastle.openpgp.PGPUtil;

import org.bouncycastle.openpgp.jcajce.JcaPGPObjectFactory;

import org.bouncycastle.openpgp.operator.jcajce.JcaKeyFingerprintCalculator;

import org.bouncycastle.openpgp.operator.jcajce.JcePGPDataEncryptorBuilder;

import org.bouncycastle.openpgp.operator.jcajce.JcePublicKeyDataDecryptorFactoryBuilder;

import org.bouncycastle.openpgp.operator.jcajce.JcePublicKeyKeyEncryptionMethodGenerator;

import org.bouncycastle.util.io.Streams;

public class KeyBasedFileProcessor {

private 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 (oinstanceof 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 = PGPExampleUtil.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 (messageinstanceof PGPCompressedData) {

PGPCompressedData cData = (PGPCompressedData) message;

                JcaPGPObjectFactory pgpFact =new JcaPGPObjectFactory(cData.getDataStream());

                message = pgpFact.nextObject();

            }

if (messageinstanceof PGPLiteralData) {

PGPLiteralData ld = (PGPLiteralData) message;

                String outFileName = ld.getFileName();

                if (outFileName.length() ==0) {

outFileName = defaultFileName;

                }else {

outFileName = defaultFileName;

                }

InputStream unc = ld.getInputStream();

                OutputStream fOut =new BufferedOutputStream(new FileOutputStream(outFileName));

                Streams.pipeAll(unc, fOut);

                fOut.close();

            }else if (messageinstanceof 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 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 = PGPExampleUtil.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 = PGPExampleUtil.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();

            }

}

}

//遍历读取文件名

    public static ListReadFileName()throws SinoSystemException {

File f =null;

//        DateUtil.getCurrentDate("yyyy-MM-dd");

//        String timerandom = DateUtil.getCurrentDate("yyyy-MM-dd").replace("-", "");

        String path ="";

//        path = "D:" + "/" + timerandom + "/encrypt";

        path ="D:/20190628/encrypt/";

        f =new File(path); //新建文件实例

        File[] list = f.listFiles(); /* 此处获取文件夹下的所有文件 */

        List fileNameList =new ArrayList();

        if (null != list && list.length >0) {

for (int i =0; i < list.length; i++) {

fileNameList.add(list[i].getName());

                System.out.println("遍历后的文件名:" + fileNameList.get(i));

            }

}else {

throw new SinoSystemException("文件夹没有相应的文件");

        }

return fileNameList;

    }

//主方法

    public static void main(String[] s)throws Exception {

Security.addProvider(new BouncyCastleProvider());

        boolean encryp =false;  //加密:true  解密:false

        if (encryp) {

String outPath ="D:\\20190628\\decrypt\\123.DAT";

            String inputPath ="D:\\20190628\\decrypt\\123.txt";

            String publicKeys ="D:\\20190628\\public\\C3B655736E8C77F83183074049F3AB440C1B1830.asc";  //公钥地址

            encryptFile(outPath, inputPath, publicKeys, true, true);

        }else {

String inputPath;

            String outPath;

            String address ="D:/20190628/decrypt/";

            String password ="1234568987";  //私钥的Key

            String privateKeys ="D:\\20190628\\private\\C3B655736E8C77F83183074049F3AB440C1B1830.asc";//私钥地址

//批量解密文件

            List fileList =ReadFileName();

            if (null != fileList) {

for (int i =0; i < fileList.size(); i++) {

inputPath ="D:/20190628/encrypt/" + fileList.get(i);  //被加密的文件

                    if (fileList.get(i).indexOf("DAT") != -1) {

outPath = address + fileList.get(i).replace("DAT", "TXT");

                        System.out.println("解密第一个文件,要解密的文件:" + inputPath +",解密出来的文件" + outPath);

                        decryptFile(inputPath, privateKeys, password.toCharArray(), outPath);

                    }else {

continue;

                    }

}

}

}

}

}
import org.bouncycastle.openpgp.*;

import org.bouncycastle.openpgp.operator.jcajce.JcaKeyFingerprintCalculator;

import org.bouncycastle.openpgp.operator.jcajce.JcePBESecretKeyDecryptorBuilder;

import java.io.BufferedInputStream;

import java.io.ByteArrayOutputStream;

import java.io.File;

import java.io.FileInputStream;

import java.io.IOException;

import java.io.InputStream;

import java.security.NoSuchProviderException;

import java.util.Iterator;

public class PGPExampleUtil {

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

    }

/**

* Search a secret key ring collection for a secret key corresponding to keyID if it

* exists.

*

    * @param pgpSec a secret key ring collection.

    * @param keyID  keyID we want.

    * @param pass  passphrase to decrypt secret key with.

    * @return the private key.

    * @throws PGPException

    * @throws NoSuchProviderException

*/

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

    }

static PGPPublicKeyreadPublicKey(String fileName)throws IOException, PGPException {

InputStream keyIn =new BufferedInputStream(new FileInputStream(fileName));

        PGPPublicKey pubKey =readPublicKey(keyIn);

        keyIn.close();

        return pubKey;

    }

/**

* A simple routine that opens a key ring file and loads the first available key

* suitable for encryption.

*

    * @param input data stream containing the public key data

    * @return the first public key found.

    * @throws IOException

    * @throws PGPException

*/

    static PGPPublicKeyreadPublicKey(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.");

    }

static PGPSecretKeyreadSecretKey(String fileName)throws IOException, PGPException {

InputStream keyIn =new BufferedInputStream(new FileInputStream(fileName));

        PGPSecretKey secKey =readSecretKey(keyIn);

        keyIn.close();

        return secKey;

    }

/**

* A simple routine that opens a key ring file and loads the first available key

* suitable for signature generation.

*

    * @param input stream to read the secret key ring collection from.

    * @return a secret key.

    * @throws IOException  on a problem with using the input stream.

    * @throws PGPException if there is an issue parsing the input stream.

*/

    static PGPSecretKeyreadSecretKey(InputStream input)throws IOException, PGPException {

PGPSecretKeyRingCollection pgpSec =new PGPSecretKeyRingCollection(

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 = pgpSec.getKeyRings();

        while (keyRingIter.hasNext()) {

PGPSecretKeyRing keyRing = (PGPSecretKeyRing) keyRingIter.next();

            Iterator keyIter = keyRing.getSecretKeys();

            while (keyIter.hasNext()) {

PGPSecretKey key = (PGPSecretKey) keyIter.next();

                if (key.isSigningKey()) {

return key;

                }

}

}

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

    }

}

 

  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 16
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 16
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值