2013. 8. 5. 11:00

인증서를 사용한 암복호화 샘플 


bouncycastle 라이브러리 이용



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
/*
 * 작성일   : 2013. 8. 05.
 * 제목      : TestRSA
 * 설명      : PGP 라이브러리를 이용한 암호화 (인증서 사용)
 */
 
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
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.PublicKey;
import java.security.SecureRandom;
import java.security.Security;
import java.util.Date;
import java.util.Iterator;
 
import javax.security.cert.CertificateException;
import javax.security.cert.X509Certificate;
 
import org.bouncycastle.bcpg.ArmoredOutputStream;
import org.bouncycastle.bcpg.CompressionAlgorithmTags;
import org.bouncycastle.bcpg.PublicKeyAlgorithmTags;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.openpgp.PGPCompressedDataGenerator;
import org.bouncycastle.openpgp.PGPEncryptedData;
import org.bouncycastle.openpgp.PGPEncryptedDataGenerator;
import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPLiteralData;
import org.bouncycastle.openpgp.PGPPublicKey;
import org.bouncycastle.openpgp.PGPPublicKeyRing;
import org.bouncycastle.openpgp.PGPPublicKeyRingCollection;
import org.bouncycastle.openpgp.PGPUtil;
import org.bouncycastle.openpgp.operator.jcajce.JcePGPDataEncryptorBuilder;
import org.bouncycastle.openpgp.operator.jcajce.JcePublicKeyKeyEncryptionMethodGenerator;
 
public class TestPGPencrypt {
 
    private static final String E_INPUT = "d:/data.txt";
    private static final String E_OUTPUT = "d:/data.pgp";
    private static final String E_KEY_FILE = "d:/XXX.crt";
    private static boolean asciiArmored = false;
    private static boolean integrityCheck = true;
 
    /**
     * @param args
     */
    public static void main(String[] args) throws Exception {
        // TODO Auto-generated method stub
        Security.addProvider(new BouncyCastleProvider());
 
        OutputStream out = new BufferedOutputStream(new FileOutputStream(E_OUTPUT));
        PGPPublicKey encKey = readPublicKey(E_KEY_FILE);
        encryptFile(out, E_INPUT, encKey, asciiArmored, integrityCheck);
        out.close();
 
    }
 
    static PGPPublicKey readPublicKey(String fileName) throws IOException, PGPException {
        InputStream keyIn = new BufferedInputStream(new FileInputStream(fileName));
        PGPPublicKey pubKey = readPublicKey(keyIn);
        keyIn.close();
        return pubKey;
    }
 
    static PGPPublicKey readPublicKey(InputStream input) throws IOException, PGPException {
        byte[] buffer = new byte[input.available()];
        input.read(buffer);
        X509Certificate x509Cert = null;
        try {
            x509Cert = X509Certificate.getInstance(buffer);
        } catch (CertificateException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        PublicKey pkey = x509Cert.getPublicKey();
                 
        PGPPublicKey publicKey = new PGPPublicKey(PublicKeyAlgorithmTags.RSA_GENERAL, pkey, new Date());
        return publicKey;
    }
 
    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 = compressFile(fileName, CompressionAlgorithmTags.UNCOMPRESSED);
 
            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();
            }
        }
    }
 
    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();
    }
}
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
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
/*
 * 작성일   : 2013. 8. 05.
 * 제목      : TestRSA
 * 설명      : PGP 라이브러리를 이용한 복호화 (인증서 사용)
 */
 
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.PrivateKey;
import java.security.Security;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Iterator;
 
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.openpgp.PGPCompressedData;
import org.bouncycastle.openpgp.PGPEncryptedDataList;
import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPLiteralData;
import org.bouncycastle.openpgp.PGPObjectFactory;
import org.bouncycastle.openpgp.PGPOnePassSignatureList;
import org.bouncycastle.openpgp.PGPPrivateKey;
import org.bouncycastle.openpgp.PGPPublicKeyEncryptedData;
import org.bouncycastle.openpgp.PGPSecretKey;
import org.bouncycastle.openpgp.PGPSecretKeyRing;
import org.bouncycastle.openpgp.PGPSecretKeyRingCollection;
import org.bouncycastle.openpgp.PGPUtil;
import org.bouncycastle.openpgp.operator.jcajce.JcePublicKeyDataDecryptorFactoryBuilder;
import org.bouncycastle.util.io.Streams;
import org.bouncycastle.util.io.pem.PemObject;
import org.bouncycastle.util.io.pem.PemReader;
 
public class TestPGPdecrypt {
 
    private static final String DE_INPUT = "d:/data.pgp";
    private static final String DE_OUTPUT = "d:/data_1.txt";
    private static final String DE_KEY_FILE = "d:/XXX.der";
     
 
    /**
     * @param args
     */
    public static void main(String[] args) throws Exception {
        // TODO Auto-generated method stub
        Security.addProvider(new BouncyCastleProvider());
         
        InputStream in = new BufferedInputStream(new FileInputStream(DE_INPUT));
        FileInputStream keyIn = new FileInputStream(DE_KEY_FILE);
        decryptFile(in, keyIn, DE_OUTPUT);
        keyIn.close();
        in.close();
    }
 
     
 
    private static void decryptFile(InputStream in, FileInputStream keyIn, String defaultFileName) throws IOException, NoSuchProviderException, NoSuchAlgorithmException, InvalidKeySpecException {
        in = PGPUtil.getDecoderStream(in);
 
 
        try {
            PGPObjectFactory pgpF = new PGPObjectFactory(in);
            PGPEncryptedDataList enc;
 
             
 
             
            Object o = pgpF.nextObject();
             
             
             
            //
            // the first object might be a PGP marker packet.
            //
            if (o instanceof PGPEncryptedDataList) {
                enc = (PGPEncryptedDataList) o;
                System.out.println("ok");
            } else {
                enc = (PGPEncryptedDataList) pgpF.nextObject();
                System.out.println("false");
            }
 
            //
            // find the secret key
            //
            Iterator it = enc.getEncryptedDataObjects();
 
             
            byte[] buffer = new byte[keyIn.available()];
            keyIn.read(buffer);
            KeySpec keySpec = new PKCS8EncodedKeySpec(buffer);
            KeyFactory kf = KeyFactory.getInstance("RSA");
            PrivateKey key = kf.generatePrivate(keySpec);
             
             
             
            PGPPublicKeyEncryptedData pbe = null;
 
            while (it.hasNext()) {
                pbe = (PGPPublicKeyEncryptedData) it.next();
            }
             
             
 
            InputStream clear = pbe.getDataStream(new JcePublicKeyDataDecryptorFactoryBuilder().setProvider("BC").build(key));
 
            PGPObjectFactory plainFact = new PGPObjectFactory(clear);
 
            Object message = plainFact.nextObject();
 
            if (message instanceof PGPCompressedData) {
                PGPCompressedData cData = (PGPCompressedData) message;
                PGPObjectFactory pgpFact = new PGPObjectFactory(cData.getDataStream());
 
                message = pgpFact.nextObject();
                 
                System.out.println("PGPCompressedData oject true");
            }
 
            if (message instanceof PGPLiteralData) {
                System.out.println("PGPLiteralData oject true");
                 
                 
                PGPLiteralData ld = (PGPLiteralData) message;
 
                String outFileName = ld.getFileName(); // 원본 파일명
                if (outFileName.length() == 0) {
                    outFileName = defaultFileName;
                }
 
                InputStream unc = ld.getInputStream();
                OutputStream fOut = new BufferedOutputStream(new FileOutputStream(defaultFileName));
 
                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()) {
                    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();
            }
        }
    }
}
Posted by sungwonpekr