KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sslexplorer > security > pki > SshtoolsPrivateKeyFormat


1 /*
2  * SSL-Explorer
3  *
4  * Copyright (C) 2003-2006 3SP LTD. All Rights Reserved
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2 of
9  * the License, or (at your option) any later version.
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public
16  * License along with this program; if not, write to the Free Software
17  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18  */

19             
20 package com.sslexplorer.security.pki;
21
22 import java.io.IOException JavaDoc;
23 import java.security.Key JavaDoc;
24 import java.security.spec.KeySpec JavaDoc;
25
26 import javax.crypto.Cipher;
27 import javax.crypto.SecretKeyFactory;
28 import javax.crypto.spec.DESedeKeySpec;
29 import javax.crypto.spec.IvParameterSpec;
30
31 import com.maverick.crypto.digests.Hash;
32 import com.maverick.util.ByteArrayReader;
33 import com.maverick.util.ByteArrayWriter;
34
35
36 /**
37  *
38  *
39  * @author $author$
40  */

41 public class SshtoolsPrivateKeyFormat extends Base64EncodedFileFormat
42     implements SshPrivateKeyFormat {
43     private static String JavaDoc BEGIN = "---- BEGIN SSHTOOLS ENCRYPTED PRIVATE KEY ----";
44     private static String JavaDoc END = "---- END SSHTOOLS ENCRYPTED PRIVATE KEY ----";
45     private int cookie = 0x52f37abe;
46
47     /**
48      * Creates a new SshtoolsPrivateKeyFormat object.
49      *
50      * @param subject
51      * @param comment
52      */

53     public SshtoolsPrivateKeyFormat(String JavaDoc subject, String JavaDoc comment) {
54         super(BEGIN, END);
55         setHeaderValue("Subject", subject);
56         setHeaderValue("Comment", comment);
57     }
58
59     /**
60      * Creates a new SshtoolsPrivateKeyFormat object.
61      */

62     public SshtoolsPrivateKeyFormat() {
63         super(BEGIN, END);
64     }
65
66     /**
67      *
68      *
69      * @return
70      */

71     public String JavaDoc getFormatType() {
72         return "SSHTools-PrivateKey-" + super.getFormatType();
73     }
74
75     /**
76      *
77      *
78      * @param formattedKey
79      *
80      * @return
81      */

82     public boolean isPassphraseProtected(byte[] formattedKey) {
83         try {
84             ByteArrayReader bar = new ByteArrayReader(getKeyBlob(formattedKey));
85             String JavaDoc type = bar.readString();
86
87             if (type.equals("none")) {
88                 return false;
89             }
90
91             if (type.equalsIgnoreCase("3des-cbc")) {
92                 return true;
93             }
94         } catch (IOException JavaDoc ioe) {
95         } catch(InvalidKeyException ex) {
96         }
97
98         return false;
99     }
100
101     /**
102      *
103      *
104      * @param formattedKey
105      * @param passphrase
106      *
107      * @return
108      *
109      * @throws InvalidKeyException
110      */

111     public byte[] decryptKeyblob(byte[] formattedKey, String JavaDoc passphrase)
112         throws InvalidKeyException {
113         try {
114             byte[] keyblob = getKeyBlob(formattedKey);
115             ByteArrayReader bar = new ByteArrayReader(keyblob);
116             String JavaDoc type = bar.readString();
117
118             if (type.equalsIgnoreCase("3des-cbc")) {
119                 // Decrypt the key
120
byte[] keydata = makePassphraseKey(passphrase);
121                 byte[] iv = new byte[8];
122
123                 if (type.equals("3DES-CBC")) {
124                     bar.read(iv);
125                 }
126
127                 keyblob = bar.readBinaryString();
128
129                 Cipher cipher = Cipher.getInstance("DESede/CBC/PKCS5Padding");
130                 KeySpec JavaDoc keyspec = new DESedeKeySpec(keydata);
131                 Key JavaDoc key = SecretKeyFactory.getInstance("DESede").generateSecret(keyspec);
132                 cipher.init(Cipher.DECRYPT_MODE, key,
133                     new IvParameterSpec(iv, 0, cipher.getBlockSize()));
134
135                 ByteArrayReader data = new ByteArrayReader(cipher.doFinal(
136                             keyblob));
137
138                 if (data.readInt() == cookie) {
139                     keyblob = data.readBinaryString();
140                 } else {
141                     throw new InvalidKeyException(
142                         "The host key is invalid, check the passphrase supplied");
143                 }
144             } else {
145                 keyblob = bar.readBinaryString();
146             }
147
148             return keyblob;
149         } catch (Exception JavaDoc aoe) {
150             throw new InvalidKeyException("Failed to read host key");
151         }
152     }
153
154     /**
155      *
156      *
157      * @param keyblob
158      * @param passphrase
159      *
160      * @return
161      */

162     public byte[] encryptKeyblob(byte[] keyblob, String JavaDoc passphrase) {
163         try {
164             ByteArrayWriter baw = new ByteArrayWriter();
165             String JavaDoc type = "none";
166
167             if (passphrase != null) {
168                 if (!passphrase.trim().equals("")) {
169                     // Encrypt the data
170
type = "3DES-CBC";
171
172                     // Decrypt the key
173
byte[] keydata = makePassphraseKey(passphrase);
174                     byte[] iv = new byte[8];
175                     Utils.getRND().nextBytes(iv);
176
177                     Cipher cipher = Cipher.getInstance(
178                             "DESede/CBC/PKCS5Padding");
179                     KeySpec JavaDoc keyspec = new DESedeKeySpec(keydata);
180                     Key JavaDoc key = SecretKeyFactory.getInstance("DESede")
181                                               .generateSecret(keyspec);
182                     cipher.init(Cipher.ENCRYPT_MODE, key,
183                         new IvParameterSpec(iv, 0, cipher.getBlockSize()));
184
185                     ByteArrayWriter data = new ByteArrayWriter();
186                     baw.writeString(type);
187                     baw.write(iv);
188                     data.writeInt(cookie);
189                     data.writeBinaryString(keyblob);
190
191                     // Encrypt and write
192
baw.writeBinaryString(cipher.doFinal(data.toByteArray()));
193
194                     return formatKey(baw.toByteArray());
195                 }
196             }
197
198             // Write the type of encryption
199
baw.writeString(type);
200
201             // Write the key blob
202
baw.writeBinaryString(keyblob);
203
204             // Now set the keyblob to our new encrpyted (or not) blob
205
return formatKey(baw.toByteArray());
206         } catch (Exception JavaDoc ioe) {
207             return null;
208         }
209     }
210
211     /**
212      *
213      *
214      * @param algorithm
215      *
216      * @return
217      */

218     public boolean supportsAlgorithm(String JavaDoc algorithm) {
219         return true;
220     }
221
222     private byte[] makePassphraseKey(String JavaDoc passphrase) {
223             // Generate the key using the passphrase
224
Hash md5 = new Hash("MD5");
225             md5.putBytes(passphrase.getBytes());
226
227             byte[] key1 = md5.doFinal();
228             md5.reset();
229             md5.putBytes(passphrase.getBytes());
230             md5.putBytes(key1);
231
232             byte[] key2 = md5.doFinal();
233             byte[] key = new byte[32];
234             System.arraycopy(key1, 0, key, 0, 16);
235             System.arraycopy(key2, 0, key, 16, 16);
236
237             return key;
238     }
239 }
240
Popular Tags