Source code: com/traxel/crypto/DHPartner.java
1 /* $Id: DHPartner.java,v 1.2 2001/03/20 00:51:19 cvsbob Exp $ */
2
3 /*
4 * DHPartner.java, class for synching Diffie Hellman partners.
5 * Copyright (C) 2001 Robert Bushman.
6 *
7 * I reserve the right to release this program under seperate license.
8 * If you require a special license grant contact Robert Bushman.
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 2
13 * of the License, or (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
23 * 02111-1307, USA.
24 */
25
26 package com.traxel.crypto;
27
28 import java.io.IOException;
29 import java.security.AlgorithmParameters;
30 import java.security.InvalidAlgorithmParameterException;
31 import java.security.InvalidKeyException;
32 import java.security.KeyFactory;
33 import java.security.KeyPair;
34 import java.security.KeyPairGenerator;
35 import java.security.NoSuchAlgorithmException;
36 import java.security.spec.InvalidKeySpecException;
37 import java.security.spec.X509EncodedKeySpec;
38 import javax.crypto.Cipher;
39 import javax.crypto.KeyAgreement;
40 import javax.crypto.NoSuchPaddingException;
41 import javax.crypto.SecretKey;
42 import javax.crypto.interfaces.DHPublicKey;
43 import javax.crypto.spec.DHParameterSpec;
44
45 public class DHPartner {
46
47 // ----------------------------------------------------------
48 // CONSTANTS
49 // ----------------------------------------------------------
50
51 private static final String PUBLIC_ALGORITHM = "DH";
52 private static final String PRIVATE_ALGORITHM = "DES";
53 private static final String TRANSFORMATION = "DES/CFB8/NoPadding";
54
55 // ----------------------------------------------------------
56 // CONSTRUCTORS
57 // ----------------------------------------------------------
58
59 public DHPartner( String name, DHParameterSpec params ) {
60 System.out.println( name + ": Initializing Crypto" );
61 setName( name );
62 setParams( params );
63 initializeKeys();
64 }
65
66 public DHPartner( String name, byte[] partnerPublicEncoded ) {
67 System.out.println( name + ": Initializing Crypto" );
68 setName( name );
69 decodePartnerKey( partnerPublicEncoded );
70 setParams( getPartnerPublicKey().getParams() );
71 initializeKeys();
72 }
73
74 public DHPartner( String name, DHPartner other ) {
75 System.out.println( name + ": Copying From " + other.getName() );
76 setName( name );
77 setParams( other.getParams() );
78 setKeyPair( other.getKeyPair() );
79 setKeyAgree( other.getKeyAgree() );
80 }
81
82 // -------------------------------------------------------------
83 // PUBLIC API
84 // -------------------------------------------------------------
85
86 public void initCipher()
87 throws InvalidKeyException,
88 InvalidAlgorithmParameterException,
89 IOException {
90 initEncryptCipher();
91 setDecryptCipher( genCipher( Cipher.DECRYPT_MODE, getCipherParams() ) );
92 }
93
94 public void initCipher( byte[] cipherParams )
95 throws InvalidKeyException,
96 InvalidAlgorithmParameterException,
97 IOException {
98 Cipher encryptCipher;
99 Cipher decryptCipher;
100
101 setEncryptCipher( genCipher( Cipher.ENCRYPT_MODE, cipherParams ) );
102 setDecryptCipher( genCipher( Cipher.DECRYPT_MODE, cipherParams ) );
103 }
104
105 public void decodePartnerKey( byte[] partnerPublicEncoded ) {
106 KeyFactory keyFactory;
107 X509EncodedKeySpec x509KeySpec;
108 DHPublicKey partnerPublicKey;
109
110 try {
111 keyFactory = KeyFactory.getInstance( PUBLIC_ALGORITHM );
112 x509KeySpec = new X509EncodedKeySpec( partnerPublicEncoded );
113 partnerPublicKey =
114 (DHPublicKey)keyFactory.generatePublic( x509KeySpec );
115 setPartnerPublicKey( partnerPublicKey );
116 } catch( NoSuchAlgorithmException e ) {
117 e.printStackTrace();
118 System.exit( 1 );
119 } catch( InvalidKeySpecException e ) {
120 e.printStackTrace();
121 System.exit( 1 );
122 }
123 }
124
125 // -------------------------------------------------------------
126 // INTERNAL API
127 // -------------------------------------------------------------
128
129 protected void initEncryptCipher() throws InvalidKeyException {
130 Cipher encryptCipher;
131 SecretKey secretKey;
132
133 try {
134 getKeyAgree().doPhase( getPartnerPublicKey(), true );
135 secretKey = getKeyAgree().generateSecret( PRIVATE_ALGORITHM );
136 encryptCipher = Cipher.getInstance( TRANSFORMATION );
137 encryptCipher.init( Cipher.ENCRYPT_MODE, secretKey );
138 setEncryptCipher( encryptCipher );
139 } catch( NoSuchAlgorithmException e ) {
140 e.printStackTrace();
141 System.exit( 1 );
142 } catch( NoSuchPaddingException e ) {
143 e.printStackTrace();
144 System.exit( 1 );
145 }
146 }
147
148 protected Cipher genCipher( int cipherMode, byte[] cipherParams )
149 throws InvalidKeyException,
150 InvalidAlgorithmParameterException,
151 IOException {
152 Cipher cipher = null;
153 SecretKey secretKey;
154 AlgorithmParameters algorithmParams;
155
156 try {
157 getKeyAgree().doPhase( getPartnerPublicKey(), true );
158 secretKey = getKeyAgree().generateSecret( PRIVATE_ALGORITHM );
159 algorithmParams =
160 AlgorithmParameters.getInstance( PRIVATE_ALGORITHM );
161 algorithmParams.init( cipherParams );
162 cipher = Cipher.getInstance( TRANSFORMATION );
163 cipher.init( cipherMode, secretKey, algorithmParams );
164 } catch( NoSuchAlgorithmException e ) {
165 e.printStackTrace();
166 System.exit( 1 );
167 } catch( NoSuchPaddingException e ) {
168 e.printStackTrace();
169 System.exit( 1 );
170 }
171 return( cipher );
172 }
173
174 protected void initializeKeys() {
175 KeyPairGenerator keyGen;
176 KeyPair keyPair;
177 KeyAgreement keyAgree;
178
179 try {
180 keyGen = KeyPairGenerator.getInstance( PUBLIC_ALGORITHM );
181 keyGen.initialize( getParams() );
182 keyPair = keyGen.generateKeyPair();
183 keyAgree = KeyAgreement.getInstance( PUBLIC_ALGORITHM );
184 keyAgree.init( keyPair.getPrivate() );
185
186 setKeyPair( keyPair );
187 setKeyAgree( keyAgree );
188 } catch( NoSuchAlgorithmException e ) {
189 e.printStackTrace();
190 System.exit( 1 );
191 } catch( InvalidAlgorithmParameterException e ) {
192 e.printStackTrace();
193 System.exit( 1 );
194 } catch( InvalidKeyException e ) {
195 e.printStackTrace();
196 System.exit( 1 );
197 }
198 }
199
200 // -------------------------------------------------------------
201 // INSTANCE PARAMTERS AND ACCESSORS
202 // -------------------------------------------------------------
203
204 // PARAMETERS
205 private String _name;
206 private DHParameterSpec _params;
207 private KeyPair _keyPair;
208 private KeyAgreement _keyAgree;
209
210 private DHPublicKey _partnerPublicKey;
211 private Cipher _decryptCipher;
212 private Cipher _encryptCipher;
213
214 // SETTERS
215 protected void setName( String name ) { _name = name; }
216 protected void setParams( DHParameterSpec params ) { _params = params; }
217 protected void setKeyPair( KeyPair keyPair ) { _keyPair = keyPair; }
218 protected void setKeyAgree( KeyAgreement keyAgree ) {
219 _keyAgree = keyAgree;
220 }
221 protected void setPartnerPublicKey( DHPublicKey partnerPublicKey ) {
222 _partnerPublicKey = partnerPublicKey;
223 }
224 protected void setEncryptCipher( Cipher encryptCipher ) {
225 _encryptCipher = encryptCipher;
226 }
227 protected void setDecryptCipher( Cipher decryptCipher ) {
228 _decryptCipher = decryptCipher;
229 }
230
231 // GETTERS
232 public String getName() { return( _name ); }
233 public DHParameterSpec getParams() { return( _params ); }
234 public KeyPair getKeyPair() { return( _keyPair ); }
235 public KeyAgreement getKeyAgree() { return( _keyAgree ); }
236 public DHPublicKey getPartnerPublicKey() { return( _partnerPublicKey ); }
237 public Cipher getEncryptCipher() { return( _encryptCipher ); }
238 public Cipher getDecryptCipher() { return( _decryptCipher ); }
239
240 // CONVENIENC GETTERS
241 public byte[] getPublicEncoded() {
242 return( getKeyPair().getPublic().getEncoded() );
243 }
244 public byte[] getCipherParams() throws IOException {
245 return( getEncryptCipherParams() );
246 }
247 public byte[] getEncryptCipherParams() throws IOException {
248 return( getEncryptCipher().getParameters().getEncoded() );
249 }
250 public byte[] getDecryptCipherParams() throws IOException {
251 return( getDecryptCipher().getParameters().getEncoded() );
252 }
253 }
254