当前位置: 首页 > 工具软件 > OpenPGP.js > 使用案例 >

PGP加解密

卫建义
2023-12-01

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

 

 


前言

PGP加解密
 


 

一、PGP是什么?

PGP全称 Pretty Good Privacy, 由Phil Zimmermann在1991年开发,开源后由各个组织开发过不同版本的PGP实现,后由IETF成立OPenPGP工作组并统一制定了一套标准,也是本文中使用的版本。

  • PGP:由Phil Zimmermann开发,最终被赛门铁克收购,被收购后是一个商业软件,需要付费。

  • OpenPGP:由开源组织规范的PGP协议,定义了加密消息、签名、私钥和用于交换公钥的证书统一标准。

  • GPG(GnuPG):符合OpenPGP标准的开源加密软件,PGP的开源实现。

二、使用步骤

1.引入库

使用maven引入库

<!--空气城堡的加解密库类-->
<dependency>
   <groupId>org.bouncycastle</groupId>
   <artifactId>bcpg-jdk15on</artifactId>
   <version>1.66</version>
</dependency>
<dependency>
	<groupId>org.bouncycastle</groupId>
	<artifactId>bcprov-jdk15on</artifactId>
	<version>1.66</version>
</dependency>
<!--工具集,非必须-->
<dependency>
   <groupId>name.neuhalfen.projects.crypto.bouncycastle.openpgp</groupId>
   <artifactId>bouncy-gpg</artifactId>
   <version>2.2.0</version>
</dependency>
<!--断言工具,非必须-->
<dependency>
   <groupId>org.assertj</groupId>
   <artifactId>assertj-core</artifactId>
   <version>3.16.1</version>
</dependency>

2.生成秘钥对

private static BouncyCastleProvider provider;
private static SecureRandom secureRandom;

static {
    provider = new BouncyCastleProvider();
    secureRandom = new SecureRandom();
    Security.addProvider(provider);
}
/**
 * <pre>
 *     to generate PGP key pairs.
 *     usage:  generatePGPKeyPair(2048, true, "tom", "my pass", "/www/pub", "/www/pri");
 *     return key pairs, str[0]=publicKey, str[1]=privateKey.
 *     if armor, return armored key string, if unarmored, return key path.
 * </pre>
 *
 * @param keyWidth   key width, 1024/2048/3072/4096, recommend 2048
 * @param armor      designate if key format with armored or not
 * @param identity   key holder's identity, recommend write as email
 * @param passPhrase password to open private key
 * @return return key pairs, str[0]=publicKey, str[1]=privateKey.
 * @throws Exception
 */
public static String[] generatePGPKeyPair(int keyWidth, boolean armor, String identity, String passPhrase,
                                          String pubKeyFile, String priKeyFile) throws Exception {
    KeyPairGenerator var1 = KeyPairGenerator.getInstance(MyPGPUtil.RSA, MyPGPUtil.PROVIDER_BC);
    var1.initialize(keyWidth);
    KeyPair var2 = var1.generateKeyPair();
    OutputStream var3;
    OutputStream var4;
    try (ByteArrayOutputStream pubKeyOut = new ByteArrayOutputStream();
         ByteArrayOutputStream priKeyOut = new ByteArrayOutputStream();
    ) {
        if (armor) {
            // key format with armored
            var3 = new ArmoredOutputStream(priKeyOut);
            var4 = new ArmoredOutputStream(pubKeyOut);
        } else {
            // key format without armored
            var3 = new FileOutputStream(priKeyFile);
            var4 = new FileOutputStream(pubKeyFile);
        }
        // the pass phrase for open private key
        char[] var11 = passPhrase.toCharArray();
        PGPDigestCalculator var6 = (new JcaPGPDigestCalculatorProviderBuilder()).build().get(2);
        JcaPGPKeyPair var7 = new JcaPGPKeyPair(1, var2, new Date());
        PGPSecretKey var8 = new PGPSecretKey(16, var7, identity, var6, (PGPSignatureSubpacketVector) null,
                (PGPSignatureSubpacketVector) null, new JcaPGPContentSignerBuilder(var7.getPublicKey().getAlgorithm(), 8),
                (new JcePBESecretKeyEncryptorBuilder(3, var6)).setProvider(MyPGPUtil.PROVIDER_BC).build(var11));
        var8.encode(var3);
        (var3).close();
        PGPPublicKey var9 = var8.getPublicKey();
        var9.encode(var4);
        (var4).close();
        // build return result
        String[] keyPair = new String[2];
        if (armor) {
            keyPair[0] = pubKeyOut.toString();
            keyPair[1] = priKeyOut.toString();
        } else {
            keyPair[0] = pubKeyFile;
            keyPair[1] = priKeyFile;
        }
        return keyPair;
    }
}

3. 加密并签名

使用接收者的公钥加密,使用发送者的私钥签名

import java.io.*;
import java.security.*;
import java.util.Date;
import java.util.Iterator;

import org.bouncycastle.bcpg.ArmoredOutputStream;
import org.bouncycastle.bcpg.HashAlgorithmTags;
import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.openpgp.*;
import org.bouncycastle.openpgp.operator.PBESecretKeyDecryptor;
import org.bouncycastle.openpgp.operator.PGPDigestCalculator;
import org.bouncycastle.openpgp.operator.bc.BcPBESecretKeyDecryptorBuilder;
import org.bouncycastle.openpgp.operator.bc.BcPGPDigestCalculatorProvider;
import org.bouncycastle.openpgp.operator.bc.BcPublicKeyDataDecryptorFactory;
import org.bouncycastle.openpgp.operator.jcajce.*;
import org.bouncycastle.util.io.Streams;
private static BouncyCastleProvider provider;
private static SecureRandom secureRandom;

static {
    provider = new BouncyCastleProvider();
    secureRandom = new SecureRandom();
    Security.addProvider(provider);
}
/**
 * encrypt with receiver's public key and sign with sender's secretKey
 *
 * @param encryptedData      data to be encrypt and sign
 * @param publicKeyPath      receiver's public key path
 * @param secretKeyPath      sender's secretKey path
 * @param password           password to open secret key
 * @param armor              define whether to armor the output data
 * @param withIntegrityCheck define whether to generate integrity check
 * @return
 * @throws Exception
 */
public static byte[] encryptAndSign(byte[] encryptedData, String publicKeyPath, String secretKeyPath,
                                    String password, boolean armor, boolean withIntegrityCheck) throws Exception {
    FileInputStream pubKey = new FileInputStream(publicKeyPath);
    FileInputStream secretKeyIn = new FileInputStream(secretKeyPath);
    PGPSecretKey secretKey = MyPGPUtil.readSecretKey(secretKeyIn);
    PGPPublicKey publicKey = MyPGPUtil.readPublicKey(pubKey);

    // output as byte data
    try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();) {
        OutputStream out = new ByteArrayOutputStream();
        if (armor) {
            out = new ArmoredOutputStream(byteArrayOutputStream);
        }
        JcePGPDataEncryptorBuilder jcePGPDataEncryptorBuilder = (new JcePGPDataEncryptorBuilder(SymmetricKeyAlgorithmTags.TRIPLE_DES))
                .setWithIntegrityPacket(withIntegrityCheck)
                .setSecureRandom(secureRandom)
                .setProvider(provider);
        PGPEncryptedDataGenerator encryptedDataGenerator = new PGPEncryptedDataGenerator(jcePGPDataEncryptorBuilder);

        if (!publicKey.isEncryptionKey()) {
            throw new IllegalArgumentException("passed in key not an encryption key!");
        } else {
            encryptedDataGenerator.addMethod((new JcePublicKeyKeyEncryptionMethodGenerator(publicKey))
                    .setProvider(new BouncyCastleProvider())
                    .setSecureRandom(secureRandom));
        }
        OutputStream encryptedOut = encryptedDataGenerator.open(out, new byte[MyPGPUtil.BUFFER_SIZE]);
        PGPCompressedDataGenerator compressedDataGenerator = new PGPCompressedDataGenerator(PGPCompressedData.ZIP);
        OutputStream compressedOut = compressedDataGenerator.open(encryptedOut, new byte[MyPGPUtil.BUFFER_SIZE]);
        // extract private key from secret key
        PGPPrivateKey privateKey = secretKey.extractPrivateKey(
                (new JcePBESecretKeyDecryptorBuilder((new JcaPGPDigestCalculatorProviderBuilder())
                        .setProvider(provider)
                        .build()))
                        .setProvider(provider)
                        .build(password.toCharArray()));
        // signer builder
        JcaPGPContentSignerBuilder jcaPGPContentSignerBuilder = (new JcaPGPContentSignerBuilder(
                secretKey.getPublicKey().getAlgorithm(), HashAlgorithmTags.SHA1))
                .setProvider(provider)
                .setDigestProvider(provider);
        PGPSignatureGenerator signatureGenerator = new PGPSignatureGenerator(jcaPGPContentSignerBuilder);
        // private key to sign
        signatureGenerator.init(PGPSignature.BINARY_DOCUMENT, privateKey);
        boolean firstTime = true;
        Iterator it = secretKey.getPublicKey().getUserIDs();
        while (it.hasNext() && firstTime) {
            PGPSignatureSubpacketGenerator spGen = new PGPSignatureSubpacketGenerator();
            spGen.setSignerUserID(false, (String) it.next());
            signatureGenerator.setHashedSubpackets(spGen.generate());
            firstTime = false;
        }
        signatureGenerator.generateOnePassVersion(false).encode(compressedOut);
        PGPLiteralDataGenerator literalDataGenerator = new PGPLiteralDataGenerator();
        OutputStream literalOut = literalDataGenerator.open(compressedOut, PGPLiteralData.BINARY, "any str", new Date(),
                new byte[MyPGPUtil.BUFFER_SIZE]);
        ByteArrayInputStream in = new ByteArrayInputStream(encryptedData);
        byte[] buf = new byte[MyPGPUtil.BUFFER_SIZE];
        int len;
        while ((len = in.read(buf)) > 0) {
            literalOut.write(buf, 0, len);
            signatureGenerator.update(buf, 0, len);
        }
        in.close();
        literalDataGenerator.close();
        signatureGenerator.generate().encode(compressedOut);
        compressedDataGenerator.close();
        encryptedDataGenerator.close();
        if (armor) {
            out.close();
        }
        byte[] bytes = byteArrayOutputStream.toByteArray();
        return bytes;
    }
}

4. 解密并验签

接收者使用自己的私钥解密,使用发送者的公钥验签。

    /**
     * check sign and decryption
     *
     * @param encData       data to be decrypt
     * @param publicKeyPath public key to check sign(sender's key)
     * @param pass          pass to open secret key, pass was generated when creating the key pair.
     * @param secretKeyPath Secret Key Path, ex: private_key_sender.asc
     * @throws IOException
     * @throws SignatureException
     * @throws PGPException
     */
    public static byte[] decryptAndVerify(byte[] encData, String publicKeyPath, String secretKeyPath,
                                          String pass) throws Exception {
        JcaKeyFingerprintCalculator jcaKeyFingerprintCalculator = new JcaKeyFingerprintCalculator();
        InputStream in = PGPUtil.getDecoderStream(new ByteArrayInputStream(encData));
        PGPObjectFactory pgpF = new PGPObjectFactory(in, jcaKeyFingerprintCalculator);
        PGPEncryptedDataList enc;
        // get obj from encryption data
        Object o = pgpF.nextObject();
        if (o instanceof PGPEncryptedDataList) {
            enc = (PGPEncryptedDataList) o;
        } else {
            enc = (PGPEncryptedDataList) pgpF.nextObject();
        }
        Iterator it = enc.getEncryptedDataObjects();
        PGPPrivateKey sKey = null;
        PGPPublicKeyEncryptedData pbe = null;
        FileInputStream secretKeyIn = new FileInputStream(secretKeyPath);
        while (sKey == null && it.hasNext()) {
            pbe = (PGPPublicKeyEncryptedData) it.next();
            PBESecretKeyDecryptor decryptor = new BcPBESecretKeyDecryptorBuilder(
                    new BcPGPDigestCalculatorProvider()).build(pass.toCharArray());
            PGPSecretKey secretKey = MyPGPUtil.readSecretKey(secretKeyIn);
            if (secretKey != null) {
                // sKey has nothing to do with it.hasNext, why put it in same block ?
                sKey = secretKey.extractPrivateKey(decryptor);
            }
        }
        if (sKey == null) {
            throw new IllegalArgumentException("Unable to find secret key to decrypt the message");
        }
//        log.debug("keyId:{}", sKey.getKeyID());
        InputStream clear = pbe.getDataStream(new BcPublicKeyDataDecryptorFactory(sKey));
        PGPObjectFactory plainFact = new PGPObjectFactory(clear, jcaKeyFingerprintCalculator);
        Object message;
        PGPOnePassSignatureList onePassSignatureList = null;
        PGPSignatureList signatureList = null;
        PGPCompressedData compressedData;
        message = plainFact.nextObject();
        ByteArrayOutputStream actualOutput = new ByteArrayOutputStream();
        while (message != null) {
            if (message instanceof PGPCompressedData) {
                compressedData = (PGPCompressedData) message;
                plainFact = new PGPObjectFactory(compressedData.getDataStream(), jcaKeyFingerprintCalculator);
                message = plainFact.nextObject();
            }
            if (message instanceof PGPLiteralData) {
                Streams.pipeAll(((PGPLiteralData) message).getInputStream(), actualOutput);
            } else if (message instanceof PGPOnePassSignatureList) {
                onePassSignatureList = (PGPOnePassSignatureList) message;
            } else if (message instanceof PGPSignatureList) {
                signatureList = (PGPSignatureList) message;
            } else {
                throw new PGPException("message unknown message type.");
            }
            message = plainFact.nextObject();
        }
        actualOutput.close();
        PGPPublicKey publicKey = null;
        byte[] output = actualOutput.toByteArray();
        if (onePassSignatureList == null || signatureList == null) {
            throw new PGPException("Poor PGP. Signatures not found.");
        } else {
            for (int i = 0; i < onePassSignatureList.size(); i++) {
                PGPOnePassSignature ops = onePassSignatureList.get(0);
                FileInputStream pubKeyIn = new FileInputStream(publicKeyPath);
                PGPPublicKeyRingCollection pgpRing = new PGPPublicKeyRingCollection(
                        PGPUtil.getDecoderStream(pubKeyIn), jcaKeyFingerprintCalculator);
                publicKey = pgpRing.getPublicKey(ops.getKeyID());
                if (publicKey != null) {
                    ops.init(new JcaPGPContentVerifierBuilderProvider().setProvider("BC"), publicKey);
                    // load data to check sign
                    ops.update(output);
                    PGPSignature signature = signatureList.get(i);
                    if (ops.verify(signature)) {
                        Iterator<?> userIds = publicKey.getUserIDs();
                        while (userIds.hasNext()) {
                            String userId = (String) userIds.next();
                            // get userId and check
                            log.debug("decryptAndVerify get userId from pubKey:{}", userId);
                        }
                    } else {
                        throw new SignatureException("Signature verification failed");
                    }
                }
            }
        }
        if (pbe.isIntegrityProtected() && !pbe.verify()) {
            throw new PGPException("Data is integrity protected but integrity is lost.");
        } else if (publicKey == null) {
            throw new SignatureException("Signature not found");
        } else {
            ByteArrayOutputStream fOut = new ByteArrayOutputStream();
            // flush output to file
            fOut.write(output);
            fOut.flush();
            IOUtils.close(fOut);
            return fOut.toByteArray();
        }
    }

6. 附文中使用的工具类

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

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

/**
 * Create by wiwi on 2020/9/22 17:53 <p>
 * Description: <p>
 * PGP Util, also see to org.bouncycastle.openpgp.examples.PGPExampleUtil
 *
 * @see org.bouncycastle.openpgp.examples.PGPExampleUtil
 * @since
 */
class MyPGPUtil {

    static final int BUFFER_SIZE = 1 << 16;
    static final String PROVIDER_BC = "BC";
    static final String RSA = "RSA";

    private MyPGPUtil() {
    }

    static byte[] compressFile(String var0, int var1) throws IOException {
        ByteArrayOutputStream var2 = new ByteArrayOutputStream();
        PGPCompressedDataGenerator var3 = new PGPCompressedDataGenerator(var1);
        PGPUtil.writeFileToLiteralData(var3.open(var2), 'b', new File(var0));
        var3.close();
        return var2.toByteArray();
    }

    static PGPPrivateKey findSecretKey(PGPSecretKeyRingCollection var0, long var1, char[] var3) throws PGPException, NoSuchProviderException {
        PGPSecretKey var4 = var0.getSecretKey(var1);
        return var4 == null ? null : var4.extractPrivateKey((new JcePBESecretKeyDecryptorBuilder()).setProvider("BC").build(var3));
    }

    static PGPPublicKey readPublicKey(String var0) throws IOException, PGPException {
        BufferedInputStream var1 = new BufferedInputStream(new FileInputStream(var0));
        PGPPublicKey var2 = readPublicKey((InputStream) var1);
        var1.close();
        return var2;
    }

    static PGPPublicKey readPublicKey(InputStream var0) throws IOException, PGPException {
        PGPPublicKeyRingCollection var1 = new PGPPublicKeyRingCollection(PGPUtil.getDecoderStream(var0), new JcaKeyFingerprintCalculator());
        Iterator var2 = var1.getKeyRings();

        while (var2.hasNext()) {
            PGPPublicKeyRing var3 = (PGPPublicKeyRing) var2.next();
            Iterator var4 = var3.getPublicKeys();

            while (var4.hasNext()) {
                PGPPublicKey var5 = (PGPPublicKey) var4.next();
                if (var5.isEncryptionKey()) {
                    return var5;
                }
            }
        }

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

    static PGPSecretKey readSecretKey(String var0) throws IOException, PGPException {
        BufferedInputStream var1 = new BufferedInputStream(new FileInputStream(var0));
        PGPSecretKey var2 = readSecretKey((InputStream) var1);
        var1.close();
        return var2;
    }

    static PGPSecretKey readSecretKey(InputStream var0) throws IOException, PGPException {
        PGPSecretKeyRingCollection var1 = new PGPSecretKeyRingCollection(PGPUtil.getDecoderStream(var0), new JcaKeyFingerprintCalculator());
        Iterator var2 = var1.getKeyRings();

        while (var2.hasNext()) {
            PGPSecretKeyRing var3 = (PGPSecretKeyRing) var2.next();
            Iterator var4 = var3.getSecretKeys();

            while (var4.hasNext()) {
                PGPSecretKey var5 = (PGPSecretKey) var4.next();
                if (var5.isSigningKey()) {
                    return var5;
                }
            }
        }

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

}

7. 测试

/**
 * Create by wiwi on 2020/9/22 18:22 <p>
 * Description: <p>
 *
 * @since
 */
public class PGPTest {

    public static void main(String[] args) throws Exception {
       // pgp2();
       
//        generatePGP_armor(); // 生成 armor 格式的密钥对
//        generatePGP_unarmored();  // 生成非 armor 格式的密钥对
    }

    private static void generatePGP_unarmored() throws Exception {
        String[] keyPair = PGP.generateUnarmoredPGPKeyPair(2048, "wiwi2019@163.com", "test passphrase", "/test/key1", "/test/key2");
        System.out.println(keyPair[0]);
        System.out.println(keyPair[1]);
    }

    private static void generatePGP_armor() throws Exception {
        String[] keyPair = PGP.generateArmoredPGPKeyPair(2048, "wiwi2019@163.com", "java passphrase");
        System.out.println(keyPair[0]);
        System.out.println(keyPair[1]);
    }


    private static void pgp2() throws Exception {
        String data = "-----hello PGP-----";
        // 将上述生成的秘钥粘贴进文件并保存
        String receiverPubKey = "/test/MY_PGP_PUB_KEY.asc";
        String senderPriKey = "/test/THIRD_PGP_PRI_KEY.asc";
        String senderPriKeyPass = "java passphrase";
        byte[] encData = data.getBytes();
        byte[] encryptAndSign = PGP.encryptAndSign(encData, receiverPubKey, senderPriKey, senderPriKeyPass);
        System.out.println(new String(encryptAndSign));
        System.out.println("--------------a separator-----------------");
        String receiverPriKey = "/test/MY_PGP_PRI_KEY.asc";
        String receiverPass = "test passphrase";
        String senderPubKey = "/test/THIRD_PGP_PUB_KEY.asc";
        byte[] verify = PGP.decryptAndVerify(encryptAndSign, senderPubKey, receiverPriKey, receiverPass);
        System.out.println(new String(verify));
    } 
}

8. 示例

8.1 生成Armor 格式的秘钥

-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: BCPG v1.66

mQENBF9rCWMBCADdPtQ0ElM9w2I7WZUPOupfdDTi8hJ1Mwi3R0YUQoIyT+9+dock
r+jS97FhB29SI7oQgh/bHGxxq0Pt7koMk6zFmOaeGqSuFHhO5DncZGDiuM+zx4n7
X9nFAVHlhlo+KcJl6ZDCrFkpNyp1eVaMjfhwTRaUNcKKRxb2+O0GwBmdjlHkjUH7
VBmwmTWSRk9KhKj77pFFpegJklQiqaepmR4/iWPwJiwgIjOk6yazlLgM1B5vvxNg
nDfDPsqzHkuSn4NxNEP3a/P9TzL2yKlUr4Bmt/XvjjPmnq5I954v5EZ60F43CZ6A
8FDK7Zj1C+pGHsU3w4DePw57X7xVfWmdYVbbABEBAAG0F21wdXJzZUBzdGF0ZWZv
cnR1bWUuY29tiQEcBBABCAAGBQJfawljAAoJEPZ2+ejYz07SLZEIAJCP7gnSqmjA
cnyz837h5FFAE5kbEys4RGgFm0VBbU5aoGcVBTEUyNEYhdNep61OjC0QHfGd6ePJ
3xkHOV/pqurCFSlOXywPh1otBK5cUa7CSPsYnve/rxieG82o17sFbwysfJUglRl4
e0AmUIBJ3xOf6p0dkxmaAO5Qdr+p0g4xNuj6Z8clCh/g8HUhSNDoPtNjP4GwT/CR
JpKscEMEL/xAZ6iygmIv0kOvhmPMgslUYRelA6R8gipHCroIc++jd4c/ZtEa5bhF
TADgOz7N8L7nIG1ktOdRg9ZTtGkwv+xCewCKdJqBEQIErjOQ7zbwIQgV+bWbLzJi
5F/cNiImOG0=
=SPVs
-----END PGP PUBLIC KEY BLOCK-----

----------------------下面是私钥---------------------

-----BEGIN PGP PRIVATE KEY BLOCK-----
Version: BCPG v1.66

lQO+BF9rCWMBCADdPtQ0ElM9w2I7WZUPOupfdDTi8hJ1Mwi3R0YUQoIyT+9+dock
r+jS97FhB29SI7oQgh/bHGxxq0Pt7koMk6zFmOaeGqSuFHhO5DncZGDiuM+zx4n7
X9nFAVHlhlo+KcJl6ZDCrFkpNyp1eVaMjfhwTRaUNcKKRxb2+O0GwBmdjlHkjUH7
VBmwmTWSRk9KhKj77pFFpegJklQiqaepmR4/iWPwJiwgIjOk6yazlLgM1B5vvxNg
nDfDPsqzHkuSn4NxNEP3a/P9TzL2yKlUr4Bmt/XvjjPmnq5I954v5EZ60F43CZ6A
8FDK7Zj1C+pGHsU3w4DePw57X7xVfWmdYVbbABEBAAH+AwMCCyTZz/1NLxxgoPxH
7mNbLvdSANetZlZc+klJq0xVVYN2NYj5ia3ZgKwJoAaaZbwADzH7xuvWPyYgqtix
qyKnom3FQBt+Yv2gV4/j6Q2Y6jSXOqKG9VxnMqjjlxlxPShcTP2EJUx5+q8GFRuy
/E/VSjcaNgnrVNCGKoVYFDM0bDLlPbZdijc+27kn1nQrsPiUKJEEbXokPBIWhB5V
zMgdsK9Pce1fvUmkTFPIKHTV+B+cYgG5t5BkyiJxdR1cobukg/7M7jgfBR6haRXp
wqBvodpizWde6yOkU+h9su+sejuqtYxoOygdJa4okkkUf+JYBw1FIg8CzJH1rWhW
RmUCcocLYz+gO98kFBNbMlXuPSjuIFu3671FlTJKKvKhAPwKtHmIPs2NX4kU9LuD
Q7AT9aIN2adHeS86G7liuyUWLKH/3biFK+Qfhid08b4c3Ovdg9VL5huIKazv+IHH
t8tI9LT3/qTXNJFMNrgERLW1W0J6e2XmQPPXXlskOM0SuDf8OgLp+402Hr3ZisS9
Kwr2FC7Ols/6G17w6zrk+m1ntinZlI1muG58y8BvYFglenTq3NwgiJiLFlSJpxS3
G+/pG5V2sptIDUdExdBnEi8q8aLGGMi6lmtI7cBiRoQA1U8Cn2j3LIFvkVFGXvok
JjHh8WxiekcRItQ1tcqwyUJ6+Ql5qGslOKK9xFDA7eO4VoO2X85nj/keXbaJd8Nm
1A/R/scO8yEbdhGGu+McdYL7fSNZbMT68ajCDzVunW7J668QUxTAg9yJtUVqHjWL
4OzeeRfVNaLUaCboTPtmT7+UFdCoSrzASLa4CjyH94q2IcdDt0INS0UEqYwuHIgv
QA71In88CqaRfleSND8kqzcmVr3dIIM0bwg4J5sTepQSqqpeOXVIkeeenqScmYJF
4bQXbXB1cnNlQHN0YXRlZm9ydHVtZS5jb22JARwEEAEIAAYFAl9rCWMACgkQ9nb5
6NjPTtItkQgAkI/uCdKqaMByfLPzfuHkUUATmRsTKzhEaAWbRUFtTlqgZxUFMRTI
0RiF016nrU6MLRAd8Z3p48nfGQc5X+mq6sIVKU5fLA+HWi0ErlxRrsJI+xie97+v
GJ4bzajXuwVvDKx8lSCVGXh7QCZQgEnfE5/qnR2TGZoA7lB2v6nSDjE26PpnxyUK
H+DwdSFI0Og+02M/gbBP8JEmkqxwQwQv/EBnqLKCYi/SQ6+GY8yCyVRhF6UDpHyC
KkcKughz76N3hz9m0RrluEVMAOA7Ps3wvucgbWS051GD1lO0aTC/7EJ7AIp0moER
AgSuM5DvNvAhCBX5tZsvMmLkX9w2IiY4bQ==
=rmYP
-----END PGP PRIVATE KEY BLOCK-----

8.2 加密并签名

-----BEGIN PGP MESSAGE-----
Version: BCPG v1.66

hQEMAzYf+y1QT6gLAQf9F2Cs6SjREWxeirf7Fu6jN1p9CmKt1n1gLFnTCi/+Xcu/
87keLBiGCaGY9SfVjPC3c+zwc2AE96w6pBgkm3sXrqAQo0yJ5+IzGnj1Y+o1JJ97
XpGKSxJVsOphFNSAa+V6NyX64C9IVU1FvRk69tSJEKDbN0VbNWw3dpOCu3JV2pGf
KjFh9GKS5pYufNePP+5z3sx4f5f3FSbvbnR/Q2QjLy4QLH8sMQH+0I4CYW0kJFcH
kqjvEjm99lDeLUKYBmdOqxPtFcYZXtvJUevaBiPI++vIHzcc/uIo67yoBnRDiRhA
fP3JHHy3y3EQIph/IZcp1bveIV7STL26fWK/aKMfutLAwAElPKKIHYLYQUJaXHi2
hdH2c87l/Odez8sUSPvDNrx+KNNgcw6Rqas4I5v9yPiY7KjtxoT6p3ZokuvP7U4o
nhG3wZW28wM5kFNdvCF3OJJfkDsu501nuCicgehcjq9kx+l4fVPwV6IxOyYmQInZ
xDgTFHEab382cLzBoEbBtrV+shceAezxy+MDwkd2o57VycxzX+Kpxnzt1MD4eMDy
SycuYQudYOeihO6d4F+bHh7T4Vqag6t6aT0TzQgs3ipunhaJqIANh5iEsTBU/41T
nVpKs0c86BEPzc3X4plK69Z/JPGVd4egXa0jiGRk6226ww6MZomJAv2j/CGOO7Qd
OoetQ8hMUsbIJEc4G2LPyIxhc2mxgXdX4Dof7qpaORz/et0M6NR+OWcs2hm7YJVu
JXKXNS+e9bi4RTghF/bA8NcN58mRmizSi6mvs573vlJJjh0nJpESZh8RJCCSf6Hi
1oUlhSms4Iea5hX5LZ3fbREEwWysK4HRg8drsHJ9Kwn21Q==
=hXUY
-----END PGP MESSAGE-----

 

 

 


总结

若需要对文件做加解密,只需要把 

ByteArrayInputStream 改为 FileInputStream, ByteArrayOutputStream 改为 FileOutputStream 即可.

 类似资料: