IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> java通过PGP加解密文件(详细) -> 正文阅读

[Java知识库]java通过PGP加解密文件(详细)


前言

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


一、使用步骤

1.加解密工具类

代码如下(示例):


private static final String PROVIDER_BC = "BC";

/**
* Encrypt data to io stream.
*
* @param data      - The data to be encrypted.
* @param out       - The io stream to store the encrypted data.
* @param fileName  - The output file name.
* @param publicKey - The stream of public key.
* @throws IOException
* @throws PGPException
*/
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();
}

/**
* Decrypt the encrypted data to io stream.
*
* @param encryptedData        - The data to be decrypted.
* @param secretKeyInputStream - The secret key.
* @param out                  - The io stream to store decrypted data.
* @throws IOException
*/
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非对称加密算法。

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-04-29 11:57:32  更:2022-04-29 12:01:08 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 2:06:17-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码