栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

java通过PGP加解密文件(详细)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

java通过PGP加解密文件(详细)

文章目录
  • 前言
  • 一、使用步骤
    • 1.加解密工具类
    • 2.测试
  • 总结


前言

根据上一节生成的pgp公钥、密钥给文件加解密,传送门 Java生成PGP的公钥和密钥


一、使用步骤 1.加解密工具类

代码如下(示例):

private static final String PROVIDER_BC = "BC";


public static void encryptToStream(byte[] data, OutputStream out, String fileName, InputStream publicKey) throws IOException, PGPException {

   byte[] compressedData = compressData(data, fileName);

   PGPPublicKey pgpPublicKey = readPublicKey(publicKey);

   PGPEncryptedDataGenerator pgpEncryptedDataGenerator = new PGPEncryptedDataGenerator(
           new JcePGPDataEncryptorBuilder(PGPEncryptedData.CAST5)
                   .setWithIntegrityPacket(true)
                   .setSecureRandom(new SecureRandom())
                   .setProvider(PROVIDER_BC));
   pgpEncryptedDataGenerator.addMethod(new JcePublicKeyKeyEncryptionMethodGenerator(pgpPublicKey).setProvider(PROVIDER_BC));

   OutputStream encryptOutputStream = pgpEncryptedDataGenerator.open(out, compressedData.length);

   encryptOutputStream.write(compressedData);
   encryptOutputStream.close();
}


public static void decryptDataToStream(InputStream encryptedData, InputStream secretKeyInputStream, OutputStream out, String passphrase) throws IOException {

   try (InputStream pgpEncryptedData = PGPUtil.getDecoderStream(encryptedData)) {
       JcaPGPObjectFactory jcaPGPObjectFactory = new JcaPGPObjectFactory(pgpEncryptedData);
       Object object = jcaPGPObjectFactory.nextObject();

       // the first object might be a PGP marker packet.
       PGPEncryptedDataList pgpEncryptedDataList;
       if (object instanceof PGPEncryptedDataList) {
           pgpEncryptedDataList = (PGPEncryptedDataList) object;
       } else {
           pgpEncryptedDataList = (PGPEncryptedDataList) jcaPGPObjectFactory.nextObject();
       }

       // find the secret key
       Iterator iterator = pgpEncryptedDataList.getEncryptedDataObjects();
       PGPPrivateKey pgpPrivateKey = null;
       PGPPublicKeyEncryptedData pgpPublicKeyEncryptedData = null;
       PGPSecretKeyRingCollection pgpSecretKeyRingCollection = new PGPSecretKeyRingCollection(PGPUtil.getDecoderStream(secretKeyInputStream), new JcaKeyFingerprintCalculator());

       while (pgpPrivateKey == null && iterator.hasNext()) {
           pgpPublicKeyEncryptedData = (PGPPublicKeyEncryptedData) iterator.next();
           pgpPrivateKey = findSecretKey(pgpSecretKeyRingCollection, pgpPublicKeyEncryptedData.getKeyID(), passphrase.toCharArray());
       }

       if (pgpPrivateKey == null) {
           throw new IllegalArgumentException("secret key for message not found.");
       }

       InputStream pgpPrivateKeyInputStream = pgpPublicKeyEncryptedData.getDataStream(new JcePublicKeyDataDecryptorFactoryBuilder().setProvider(PROVIDER_BC).build(pgpPrivateKey));
       JcaPGPObjectFactory pgpPrivateKey_jcaPGPObjectFactory = new JcaPGPObjectFactory(pgpPrivateKeyInputStream);
       Object message = pgpPrivateKey_jcaPGPObjectFactory.nextObject();

       if (message instanceof PGPCompressedData) {
           PGPCompressedData pgpCompressedData = (PGPCompressedData) message;
           JcaPGPObjectFactory pgpFact = new JcaPGPObjectFactory(pgpCompressedData.getDataStream());

           message = pgpFact.nextObject();
       }

       if (message instanceof PGPLiteralData) {
           PGPLiteralData pgpLiteralData = (PGPLiteralData) message;
           InputStream unc = pgpLiteralData.getInputStream();
           Streams.pipeAll(unc, out);

       } 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 (pgpPublicKeyEncryptedData.isIntegrityProtected()) {
           if (!pgpPublicKeyEncryptedData.verify()) {
               log.error("message failed integrity check");
           } else {
               log.info("message integrity check passed");
           }
       } else {
           log.error("no message integrity check");
       }
   } catch (PGPException e) {
       log.error(e.getMessage(), e);
       if (e.getUnderlyingException() != null) {
           log.error(e.getUnderlyingException().getMessage(), e.getUnderlyingException());
       }
   }
}

public static byte[] compressData(byte[] data, String fileName) throws IOException {

   ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
   PGPCompressedDataGenerator pgpCompressedDataGenerator = new PGPCompressedDataGenerator(CompressionAlgorithmTags.ZIP);
   OutputStream compressStream = pgpCompressedDataGenerator.open(byteArrayOutputStream);

   PGPLiteralDataGenerator pgpLiteralDataGenerator = new PGPLiteralDataGenerator();
   // we want to generate compressed data. This might be a user option later,
   OutputStream pgpOutputStream = pgpLiteralDataGenerator.open(compressStream,
           PGPLiteralData.BINARY,
           fileName,
           data.length,
           new Date()
   );

   // in which case we would pass in bOut.
   pgpOutputStream.write(data);
   pgpOutputStream.close();
   compressStream.close();

   return byteArrayOutputStream.toByteArray();
}

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

   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.");
}

public static PGPPrivateKey findSecretKey(PGPSecretKeyRingCollection pgpSecretKeyRingCollection, long keyID, char[] pass) throws PGPException {

   PGPSecretKey pgpSecretKey = pgpSecretKeyRingCollection.getSecretKey(keyID);
   if (pgpSecretKey == null) return null;

   PBESecretKeyDecryptor pbeSecretKeyDecryptor = new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(pass);
   return pgpSecretKey.extractPrivateKey(pbeSecretKeyDecryptor);

}
2.测试

代码如下(示例):

private static void encrypt() throws Exception {
    //要加密的文件名
    String dataPath = "template.csv";
    InputStream inputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream(dataPath);
    // 读取classes下pgp文件夹的public key
    InputStream pubKey = new ClassPathResource("pgp/PUBLIC_KEY_2048.asc").getInputStream();
    byte[] encData = toByteArray(inputStream);
    //加密后的文件名
    FileOutputStream fileOutputStream = new FileOutputStream("template-encrypt.csv");
    //加密
    encryptToStream(encData, fileOutputStream, "template-encrypt.csv", pubKey);
}

private static void decrypt() throws Exception{
    InputStream encryptedData = Thread.currentThread().getContextClassLoader().getResourceAsStream("template-encrypt.csv");
    // 读取classes下pgp文件夹的private key
    InputStream secretKey = new ClassPathResource("pgp/PRIVATE_KEY_2048.asc").getInputStream();
    // 解密后的 文件
    FileOutputStream fileOutputStream = new FileOutputStream("template-decrypt.csv");
    decryptDataToStream(encryptedData, secretKey, fileOutputStream, "");
}

public static void main(String[] args) throws Exception {
	encrypt();
	decrypt();
}

总结

通过公钥给文件加密,私钥给文件解密,RSA非对称加密算法。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/846059.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号