基于Java代码进行GPG加解密

依赖

1
2
3
4
5
6
<!-- https://mvnrepository.com/artifact/org.bouncycastle/bcpg-jdk15on -->
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcpg-jdk15on</artifactId>
<version>1.65</version>
</dependency>

初始化

1
Security.addProvider(new BouncyCastleProvider());

辅助类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
@Slf4j
public class PGPFileProcessor {

public static void decryptFile(String inputFilePath, String keyFilePath, char[] passWd, String outputFilePath)
throws IOException, NoSuchProviderException {
InputStream in = new BufferedInputStream(new FileInputStream(inputFilePath));
InputStream keyIn = new BufferedInputStream(new FileInputStream(keyFilePath));
decryptFile(in, keyIn, passWd, outputFilePath);
keyIn.close();
in.close();
}

public static void decryptFile(File inputFile, String keyFilePath, char[] passWd, File outputFile)
throws IOException, NoSuchProviderException {
InputStream in = new BufferedInputStream(new FileInputStream(inputFile));
InputStream keyIn = new BufferedInputStream(new FileInputStream(keyFilePath));
decryptFile(in, keyIn, passWd, outputFile.getAbsolutePath());
keyIn.close();
in.close();
}

/**
* decrypt the passed in message stream
*/
private static void decryptFile(InputStream in, InputStream keyIn, char[] passWd, String outputFilePath)
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<PGPEncryptedData> 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 = PGPHelper.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 outFilePath = ld.getFileName();
if (outFilePath.length() == 0) {
outFilePath = outputFilePath;
} else {
outFilePath = outputFilePath;
}
InputStream unc = ld.getInputStream();
OutputStream fOut = new BufferedOutputStream(new FileOutputStream(outFilePath));
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()) {
log.error("PGP.decryptFile: message failed integrity check");
} else {
log.info("PGP.decryptFile: message integrity check passed");
}
} else {
log.error("PGP.decryptFile: no message integrity check");
}
} catch (PGPException e) {
log.error("PGP.decryptFile exception: ", e);
if (e.getUnderlyingException() != null) {
log.error("PGP.decryptFile underlying exception: ", e.getUnderlyingException());
}
}
}

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

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

try {
byte[] bytes = PGPHelper.compressFile(inputFilePath, 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) {
log.error("PGP.encryptFile exception: ", e);
if (e.getUnderlyingException() != null) {
log.error("PGP.encryptFile underlying exception: ", e.getUnderlyingException());
}
}
}

//主方法
public static void main(String[] s) throws Exception {
Security.addProvider(new BouncyCastleProvider());
String inputPath = "E:\\AppBlog\\test.csv.gpg";
String outputPath = "E:\\AppBlog\\test.csv";
String password = "appblog.cn"; //私钥的Key
String privateKey = "E:\\AppBlog\\test.key"; //私钥地址
decryptFile(inputPath, privateKey, password.toCharArray(), outputPath);
}

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
public class PGPHelper {

public 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
*/
public 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));
}

public static PGPPublicKey readPublicKey(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
*/

public 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<PGPPublicKeyRing> keyRingIter = pgpPub.getKeyRings();
while (keyRingIter.hasNext()) {
PGPPublicKeyRing keyRing = keyRingIter.next();
Iterator<PGPPublicKey> keyIter = keyRing.getPublicKeys();
while (keyIter.hasNext()) {
PGPPublicKey key = keyIter.next();
if (key.isEncryptionKey()) {
return key;
}
}
}
throw new IllegalArgumentException("Can't find encryption key in key ring.");
}

public static PGPSecretKey readSecretKey(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.
*/
public static PGPSecretKey readSecretKey(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<PGPSecretKeyRing> keyRingIter = pgpSec.getKeyRings();
while (keyRingIter.hasNext()) {
PGPSecretKeyRing keyRing = keyRingIter.next();
Iterator<PGPSecretKey> keyIter = keyRing.getSecretKeys();
while (keyIter.hasNext()) {
PGPSecretKey key = keyIter.next();
if (key.isSigningKey()) {
return key;
}
}
}
throw new IllegalArgumentException("Can't find signing key in key ring.");
}

}

Powered by AppBlog.CN     浙ICP备14037229号

Copyright © 2012 - 2020 APP开发技术博客 All Rights Reserved.

访客数 : | 访问量 :