Source Code Cross Referenced for PGPEncryptedDataGenerator.java in  » Security » Bouncy-Castle » org » bouncycastle » openpgp » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Security » Bouncy Castle » org.bouncycastle.openpgp 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        package org.bouncycastle.openpgp;
002:
003:        import org.bouncycastle.bcpg.BCPGOutputStream;
004:        import org.bouncycastle.bcpg.ContainedPacket;
005:        import org.bouncycastle.bcpg.HashAlgorithmTags;
006:        import org.bouncycastle.bcpg.PacketTags;
007:        import org.bouncycastle.bcpg.PublicKeyEncSessionPacket;
008:        import org.bouncycastle.bcpg.S2K;
009:        import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags;
010:        import org.bouncycastle.bcpg.SymmetricKeyEncSessionPacket;
011:
012:        import javax.crypto.Cipher;
013:        import javax.crypto.CipherOutputStream;
014:        import javax.crypto.spec.IvParameterSpec;
015:        import java.io.IOException;
016:        import java.io.OutputStream;
017:        import java.math.BigInteger;
018:        import java.security.DigestOutputStream;
019:        import java.security.Key;
020:        import java.security.MessageDigest;
021:        import java.security.NoSuchProviderException;
022:        import java.security.SecureRandom;
023:        import java.util.ArrayList;
024:        import java.util.List;
025:
026:        /**
027:         *  Generator for encrypted objects.
028:         */
029:        public class PGPEncryptedDataGenerator implements 
030:                SymmetricKeyAlgorithmTags, StreamGenerator {
031:            private BCPGOutputStream pOut;
032:            private CipherOutputStream cOut;
033:            private Cipher c;
034:            private boolean withIntegrityPacket = false;
035:            private boolean oldFormat = false;
036:            private DigestOutputStream digestOut;
037:
038:            private abstract class EncMethod extends ContainedPacket {
039:                protected byte[] sessionInfo;
040:                protected int encAlgorithm;
041:                protected Key key;
042:
043:                public abstract void addSessionInfo(byte[] sessionInfo)
044:                        throws Exception;
045:            }
046:
047:            private class PBEMethod extends EncMethod {
048:                S2K s2k;
049:
050:                PBEMethod(int encAlgorithm, S2K s2k, Key key) {
051:                    this .encAlgorithm = encAlgorithm;
052:                    this .s2k = s2k;
053:                    this .key = key;
054:                }
055:
056:                public Key getKey() {
057:                    return key;
058:                }
059:
060:                public void addSessionInfo(byte[] sessionInfo) throws Exception {
061:                    String cName = PGPUtil.getSymmetricCipherName(encAlgorithm);
062:                    Cipher c = Cipher.getInstance(cName + "/CFB/NoPadding",
063:                            defProvider);
064:
065:                    c.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(
066:                            new byte[c.getBlockSize()]), rand);
067:
068:                    this .sessionInfo = c.doFinal(sessionInfo, 0,
069:                            sessionInfo.length - 2);
070:                }
071:
072:                public void encode(BCPGOutputStream pOut) throws IOException {
073:                    SymmetricKeyEncSessionPacket pk = new SymmetricKeyEncSessionPacket(
074:                            encAlgorithm, s2k, sessionInfo);
075:
076:                    pOut.writePacket(pk);
077:                }
078:            }
079:
080:            private class PubMethod extends EncMethod {
081:                PGPPublicKey pubKey;
082:                BigInteger[] data;
083:
084:                PubMethod(PGPPublicKey pubKey) {
085:                    this .pubKey = pubKey;
086:                }
087:
088:                public void addSessionInfo(byte[] sessionInfo) throws Exception {
089:                    Cipher c;
090:
091:                    switch (pubKey.getAlgorithm()) {
092:                    case PGPPublicKey.RSA_ENCRYPT:
093:                    case PGPPublicKey.RSA_GENERAL:
094:                        c = Cipher.getInstance("RSA/ECB/PKCS1Padding",
095:                                defProvider);
096:                        break;
097:                    case PGPPublicKey.ELGAMAL_ENCRYPT:
098:                    case PGPPublicKey.ELGAMAL_GENERAL:
099:                        c = Cipher.getInstance("ElGamal/ECB/PKCS1Padding",
100:                                defProvider);
101:                        break;
102:                    case PGPPublicKey.DSA:
103:                        throw new PGPException("Can't use DSA for encryption.");
104:                    case PGPPublicKey.ECDSA:
105:                        throw new PGPException(
106:                                "Can't use ECDSA for encryption.");
107:                    default:
108:                        throw new PGPException("unknown asymmetric algorithm: "
109:                                + pubKey.getAlgorithm());
110:                    }
111:
112:                    Key key = pubKey.getKey(defProvider);
113:
114:                    c.init(Cipher.ENCRYPT_MODE, key);
115:
116:                    byte[] encKey = c.doFinal(sessionInfo);
117:
118:                    switch (pubKey.getAlgorithm()) {
119:                    case PGPPublicKey.RSA_ENCRYPT:
120:                    case PGPPublicKey.RSA_GENERAL:
121:                        data = new BigInteger[1];
122:
123:                        data[0] = new BigInteger(1, encKey);
124:                        break;
125:                    case PGPPublicKey.ELGAMAL_ENCRYPT:
126:                    case PGPPublicKey.ELGAMAL_GENERAL:
127:                        byte[] b1 = new byte[encKey.length / 2];
128:                        byte[] b2 = new byte[encKey.length / 2];
129:
130:                        System.arraycopy(encKey, 0, b1, 0, b1.length);
131:                        System.arraycopy(encKey, b1.length, b2, 0, b2.length);
132:
133:                        data = new BigInteger[2];
134:                        data[0] = new BigInteger(1, b1);
135:                        data[1] = new BigInteger(1, b2);
136:                        break;
137:                    default:
138:                        throw new PGPException("unknown asymmetric algorithm: "
139:                                + encAlgorithm);
140:                    }
141:                }
142:
143:                public void encode(BCPGOutputStream pOut) throws IOException {
144:                    PublicKeyEncSessionPacket pk = new PublicKeyEncSessionPacket(
145:                            pubKey.getKeyID(), pubKey.getAlgorithm(), data);
146:
147:                    pOut.writePacket(pk);
148:                }
149:            }
150:
151:            private List methods = new ArrayList();
152:            private int defAlgorithm;
153:            private SecureRandom rand;
154:            private String defProvider;
155:
156:            /**
157:             * Base constructor.
158:             *
159:             * @param encAlgorithm the symmetric algorithm to use.
160:             * @param rand source of randomness
161:             * @param provider the provider to use for encryption algorithms.
162:             */
163:            public PGPEncryptedDataGenerator(int encAlgorithm,
164:                    SecureRandom rand, String provider) {
165:                this .defAlgorithm = encAlgorithm;
166:                this .rand = rand;
167:                this .defProvider = provider;
168:            }
169:
170:            /**
171:             * Creates a cipher stream which will have an integrity packet
172:             * associated with it.
173:             * 
174:             * @param encAlgorithm
175:             * @param withIntegrityPacket
176:             * @param rand
177:             * @param provider
178:             */
179:            public PGPEncryptedDataGenerator(int encAlgorithm,
180:                    boolean withIntegrityPacket, SecureRandom rand,
181:                    String provider) {
182:                this .defAlgorithm = encAlgorithm;
183:                this .rand = rand;
184:                this .defProvider = provider;
185:                this .withIntegrityPacket = withIntegrityPacket;
186:            }
187:
188:            /**
189:             * Base constructor.
190:             *
191:             * @param encAlgorithm the symmetric algorithm to use.
192:             * @param rand source of randomness
193:             * @param oldFormat PGP 2.6.x compatability required.
194:             * @param provider the provider to use for encryption algorithms.
195:             */
196:            public PGPEncryptedDataGenerator(int encAlgorithm,
197:                    SecureRandom rand, boolean oldFormat, String provider) {
198:                this .defAlgorithm = encAlgorithm;
199:                this .rand = rand;
200:                this .defProvider = provider;
201:                this .oldFormat = oldFormat;
202:            }
203:
204:            /**
205:             * Add a PBE encryption method to the encrypted object.
206:             * 
207:             * @param passPhrase
208:             * @throws NoSuchProviderException
209:             * @throws PGPException
210:             */
211:            public void addMethod(char[] passPhrase)
212:                    throws NoSuchProviderException, PGPException {
213:                byte[] iv = new byte[8];
214:
215:                rand.nextBytes(iv);
216:
217:                S2K s2k = new S2K(HashAlgorithmTags.SHA1, iv, 0x60);
218:
219:                methods.add(new PBEMethod(defAlgorithm, s2k, PGPUtil
220:                        .makeKeyFromPassPhrase(defAlgorithm, s2k, passPhrase,
221:                                defProvider)));
222:            }
223:
224:            /**
225:             * Add a public key encrypted session key to the encrypted object.
226:             * 
227:             * @param key
228:             * @throws NoSuchProviderException
229:             * @throws PGPException
230:             */
231:            public void addMethod(PGPPublicKey key)
232:                    throws NoSuchProviderException, PGPException {
233:                if (!key.isEncryptionKey()) {
234:                    throw new IllegalArgumentException(
235:                            "passed in key not an encryption key!");
236:                }
237:
238:                methods.add(new PubMethod(key));
239:            }
240:
241:            private void addCheckSum(byte[] sessionInfo) {
242:                int check = 0;
243:
244:                for (int i = 1; i != sessionInfo.length - 2; i++) {
245:                    check += sessionInfo[i] & 0xff;
246:                }
247:
248:                sessionInfo[sessionInfo.length - 2] = (byte) (check >> 8);
249:                sessionInfo[sessionInfo.length - 1] = (byte) (check);
250:            }
251:
252:            private byte[] createSessionInfo(int algorithm, Key key) {
253:                byte[] keyBytes = key.getEncoded();
254:                byte[] sessionInfo = new byte[keyBytes.length + 3];
255:                sessionInfo[0] = (byte) algorithm;
256:                System.arraycopy(keyBytes, 0, sessionInfo, 1, keyBytes.length);
257:                addCheckSum(sessionInfo);
258:                return sessionInfo;
259:            }
260:
261:            /**
262:             * If buffer is non null stream assumed to be partial, otherwise the length will be used
263:             * to output a fixed length packet. The stream can be closed off by either calling close()
264:             * on the stream or close() on the generator.
265:             * 
266:             * @param out
267:             * @param length
268:             * @param buffer
269:             * @return
270:             * @throws IOException
271:             * @throws PGPException
272:             * @throws IllegalStateException
273:             */
274:            private OutputStream open(OutputStream out, long length,
275:                    byte[] buffer) throws IOException, PGPException,
276:                    IllegalStateException {
277:                if (cOut != null) {
278:                    throw new IllegalStateException(
279:                            "generator already in open state");
280:                }
281:
282:                if (methods.size() == 0) {
283:                    throw new IllegalStateException(
284:                            "no encryption methods specified");
285:                }
286:
287:                Key key = null;
288:
289:                pOut = new BCPGOutputStream(out);
290:
291:                if (methods.size() == 1) {
292:                    if (methods.get(0) instanceof  PBEMethod) {
293:                        PBEMethod m = (PBEMethod) methods.get(0);
294:
295:                        key = m.getKey();
296:                    } else {
297:                        key = PGPUtil.makeRandomKey(defAlgorithm, rand);
298:                        byte[] sessionInfo = createSessionInfo(defAlgorithm,
299:                                key);
300:
301:                        PubMethod m = (PubMethod) methods.get(0);
302:
303:                        try {
304:                            m.addSessionInfo(sessionInfo);
305:                        } catch (Exception e) {
306:                            throw new PGPException(
307:                                    "exception encrypting session key", e);
308:                        }
309:                    }
310:
311:                    pOut.writePacket((ContainedPacket) methods.get(0));
312:                } else // multiple methods
313:                {
314:                    key = PGPUtil.makeRandomKey(defAlgorithm, rand);
315:                    byte[] sessionInfo = createSessionInfo(defAlgorithm, key);
316:
317:                    for (int i = 0; i != methods.size(); i++) {
318:                        EncMethod m = (EncMethod) methods.get(i);
319:
320:                        try {
321:                            m.addSessionInfo(sessionInfo);
322:                        } catch (Exception e) {
323:                            throw new PGPException(
324:                                    "exception encrypting session key", e);
325:                        }
326:
327:                        pOut.writePacket(m);
328:                    }
329:                }
330:
331:                String cName = PGPUtil.getSymmetricCipherName(defAlgorithm);
332:
333:                if (cName == null) {
334:                    throw new PGPException("null cipher specified");
335:                }
336:
337:                try {
338:                    if (withIntegrityPacket) {
339:                        c = Cipher.getInstance(cName + "/CFB/NoPadding",
340:                                defProvider);
341:                    } else {
342:                        c = Cipher.getInstance(cName + "/OpenPGPCFB/NoPadding",
343:                                defProvider);
344:                    }
345:
346:                    c.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(
347:                            new byte[c.getBlockSize()]));
348:
349:                    if (buffer == null) {
350:                        //
351:                        // we have to add block size + 2 for the generated IV and + 1 + 22 if integrity protected
352:                        //
353:                        if (withIntegrityPacket) {
354:                            pOut = new BCPGOutputStream(out,
355:                                    PacketTags.SYM_ENC_INTEGRITY_PRO, length
356:                                            + c.getBlockSize() + 2 + 1 + 22);
357:                            pOut.write(1); // version number
358:                        } else {
359:                            pOut = new BCPGOutputStream(out,
360:                                    PacketTags.SYMMETRIC_KEY_ENC, length
361:                                            + c.getBlockSize() + 2, oldFormat);
362:                        }
363:                    } else {
364:                        if (withIntegrityPacket) {
365:                            pOut = new BCPGOutputStream(out,
366:                                    PacketTags.SYM_ENC_INTEGRITY_PRO, buffer);
367:                            pOut.write(1); // version number
368:                        } else {
369:                            pOut = new BCPGOutputStream(out,
370:                                    PacketTags.SYMMETRIC_KEY_ENC, buffer);
371:                        }
372:                    }
373:
374:                    OutputStream genOut = cOut = new CipherOutputStream(pOut, c);
375:
376:                    if (withIntegrityPacket) {
377:                        String digestName = PGPUtil
378:                                .getDigestName(HashAlgorithmTags.SHA1);
379:                        MessageDigest digest = MessageDigest.getInstance(
380:                                digestName, defProvider);
381:                        genOut = digestOut = new DigestOutputStream(cOut,
382:                                digest);
383:                    }
384:
385:                    byte[] inLineIv = new byte[c.getBlockSize() + 2];
386:                    rand.nextBytes(inLineIv);
387:                    inLineIv[inLineIv.length - 1] = inLineIv[inLineIv.length - 3];
388:                    inLineIv[inLineIv.length - 2] = inLineIv[inLineIv.length - 4];
389:
390:                    genOut.write(inLineIv);
391:
392:                    return new WrappedGeneratorStream(genOut, this );
393:                } catch (Exception e) {
394:                    throw new PGPException("Exception creating cipher", e);
395:                }
396:            }
397:
398:            /**
399:             * Return an outputstream which will encrypt the data as it is written
400:             * to it. The stream can be closed off by either calling close()
401:             * on the stream or close() on the generator.
402:             * 
403:             * @param out
404:             * @param length
405:             * @return OutputStream
406:             * @throws IOException
407:             * @throws PGPException
408:             */
409:            public OutputStream open(OutputStream out, long length)
410:                    throws IOException, PGPException {
411:                return this .open(out, length, null);
412:            }
413:
414:            /**
415:             * Return an outputstream which will encrypt the data as it is written
416:             * to it. The stream will be written out in chunks according to the size of the
417:             * passed in buffer. The stream can be closed off by either calling close()
418:             * on the stream or close() on the generator.
419:             * <p>
420:             * <b>Note</b>: if the buffer is not a power of 2 in length only the largest power of 2
421:             * bytes worth of the buffer will be used.
422:             * 
423:             * @param out
424:             * @param buffer the buffer to use.
425:             * @return OutputStream
426:             * @throws IOException
427:             * @throws PGPException
428:             */
429:            public OutputStream open(OutputStream out, byte[] buffer)
430:                    throws IOException, PGPException {
431:                return this .open(out, 0, buffer);
432:            }
433:
434:            /**
435:             * Close off the encrypted object - this is equivalent to calling close on the stream
436:             * returned by the open() method.
437:             * 
438:             * @throws IOException
439:             */
440:            public void close() throws IOException {
441:                if (cOut != null) {
442:                    if (digestOut != null) {
443:                        //
444:                        // hand code a mod detection packet
445:                        //
446:                        BCPGOutputStream bOut = new BCPGOutputStream(digestOut,
447:                                PacketTags.MOD_DETECTION_CODE, 20);
448:
449:                        bOut.flush();
450:                        digestOut.flush();
451:
452:                        byte[] dig = digestOut.getMessageDigest().digest();
453:
454:                        cOut.write(dig);
455:                    }
456:
457:                    cOut.flush();
458:
459:                    try {
460:                        pOut.write(c.doFinal());
461:                        pOut.finish();
462:                    } catch (Exception e) {
463:                        throw new IOException(e.toString());
464:                    }
465:
466:                    cOut = null;
467:                    pOut = null;
468:                }
469:            }
470:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.