1 | |
---|
2 | import java.security.*; |
---|
3 | import java.io.IOException; |
---|
4 | import java.io.InputStream; |
---|
5 | import java.io.FileInputStream; |
---|
6 | import java.io.DataInputStream; |
---|
7 | import java.io.ByteArrayInputStream; |
---|
8 | import java.io.FileOutputStream; |
---|
9 | import java.security.spec.*; |
---|
10 | import java.security.cert.Certificate; |
---|
11 | import java.security.cert.CertificateFactory; |
---|
12 | import java.util.Collection; |
---|
13 | import java.util.Iterator; |
---|
14 | |
---|
15 | /** |
---|
16 | * ImportKey.java |
---|
17 | * |
---|
18 | * <p>This class imports a key and a certificate into a keystore |
---|
19 | * (<code>$home/keystore.ImportKey</code>). If the keystore is |
---|
20 | * already present, it is simply deleted. Both the key and the |
---|
21 | * certificate file must be in <code>DER</code>-format. The key must be |
---|
22 | * encoded with <code>PKCS#8</code>-format. The certificate must be |
---|
23 | * encoded in <code>X.509</code>-format.</p> |
---|
24 | * |
---|
25 | * <p>Key format:</p> |
---|
26 | * <p><code>openssl pkcs8 -topk8 -nocrypt -in YOUR.KEY -out YOUR.KEY.der |
---|
27 | * -outform der</code></p> |
---|
28 | * <p>Format of the certificate:</p> |
---|
29 | * <p><code>openssl x509 -in YOUR.CERT -out YOUR.CERT.der -outform |
---|
30 | * der</code></p> |
---|
31 | * <p>Import key and certificate:</p> |
---|
32 | * <p><code>java comu.ImportKey YOUR.KEY.der YOUR.CERT.der</code></p><br /> |
---|
33 | * |
---|
34 | * <p><em>Caution:</em> the old <code>keystore.ImportKey</code>-file is |
---|
35 | * deleted and replaced with a keystore only containing <code>YOUR.KEY</code> |
---|
36 | * and <code>YOUR.CERT</code>. The keystore and the key has no password; |
---|
37 | * they can be set by the <code>keytool -keypasswd</code>-command for setting |
---|
38 | * the key password, and the <code>keytool -storepasswd</code>-command to set |
---|
39 | * the keystore password. |
---|
40 | * <p>The key and the certificate is stored under the alias |
---|
41 | * <code>importkey</code>; to change this, use <code>keytool -keyclone</code>. |
---|
42 | * |
---|
43 | * Created: Fri Apr 13 18:15:07 2001 |
---|
44 | * Updated: Fri Apr 19 11:03:00 2002 |
---|
45 | * |
---|
46 | * @author Joachim Karrer, Jens Carlberg |
---|
47 | * @version 1.1 |
---|
48 | **/ |
---|
49 | public class ImportKey { |
---|
50 | |
---|
51 | /** |
---|
52 | * <p>Creates an InputStream from a file, and fills it with the complete |
---|
53 | * file. Thus, available() on the returned InputStream will return the |
---|
54 | * full number of bytes the file contains</p> |
---|
55 | * @param fname The filename |
---|
56 | * @return The filled InputStream |
---|
57 | * @exception IOException, if the Streams couldn't be created. |
---|
58 | **/ |
---|
59 | private static InputStream fullStream ( String fname ) throws IOException { |
---|
60 | FileInputStream fis = new FileInputStream(fname); |
---|
61 | DataInputStream dis = new DataInputStream(fis); |
---|
62 | byte[] bytes = new byte[dis.available()]; |
---|
63 | dis.readFully(bytes); |
---|
64 | ByteArrayInputStream bais = new ByteArrayInputStream(bytes); |
---|
65 | return bais; |
---|
66 | } |
---|
67 | |
---|
68 | /** |
---|
69 | * <p>Takes two file names for a key and the certificate for the key, |
---|
70 | * and imports those into a keystore. Optionally it takes an alias |
---|
71 | * for the key. |
---|
72 | * <p>The first argument is the filename for the key. The key should be |
---|
73 | * in PKCS8-format. |
---|
74 | * <p>The second argument is the filename for the certificate for the key. |
---|
75 | * <p>If a third argument is given it is used as the alias. If missing, |
---|
76 | * the key is imported with the alias importkey |
---|
77 | * <p>The name of the keystore file can be controlled by setting |
---|
78 | * the keystore property (java -Dkeystore=mykeystore). If no name |
---|
79 | * is given, the file is named <code>keystore.ImportKey</code> |
---|
80 | * and placed in your home directory. |
---|
81 | * @param args [0] Name of the key file, [1] Name of the certificate file |
---|
82 | * [2] Alias for the key. |
---|
83 | **/ |
---|
84 | public static void main ( String args[]) { |
---|
85 | |
---|
86 | // change this if you want another password by default |
---|
87 | String keypass = "importkey"; |
---|
88 | |
---|
89 | // change this if you want another alias by default |
---|
90 | String defaultalias = "importkey"; |
---|
91 | |
---|
92 | // change this if you want another keystorefile by default |
---|
93 | String keystorename = System.getProperty("keystore"); |
---|
94 | |
---|
95 | if (keystorename == null) |
---|
96 | keystorename = System.getProperty("user.home")+ |
---|
97 | System.getProperty("file.separator")+ |
---|
98 | "keystore.ImportKey"; // especially this ;-) |
---|
99 | |
---|
100 | |
---|
101 | // parsing command line input |
---|
102 | String keyfile = ""; |
---|
103 | String certfile = ""; |
---|
104 | if (args.length < 2 || args.length>3) { |
---|
105 | System.out.println("Usage: java comu.ImportKey keyfile certfile [alias]"); |
---|
106 | System.exit(0); |
---|
107 | } else { |
---|
108 | keyfile = args[0]; |
---|
109 | certfile = args[1]; |
---|
110 | if (args.length>2) |
---|
111 | defaultalias = args[2]; |
---|
112 | } |
---|
113 | |
---|
114 | try { |
---|
115 | // initializing and clearing keystore |
---|
116 | KeyStore ks = KeyStore.getInstance("JKS", "SUN"); |
---|
117 | ks.load( null , keypass.toCharArray()); |
---|
118 | System.out.println("Using keystore-file : "+keystorename); |
---|
119 | ks.store(new FileOutputStream ( keystorename ), |
---|
120 | keypass.toCharArray()); |
---|
121 | ks.load(new FileInputStream ( keystorename ), |
---|
122 | keypass.toCharArray()); |
---|
123 | |
---|
124 | // loading Key |
---|
125 | InputStream fl = fullStream (keyfile); |
---|
126 | byte[] key = new byte[fl.available()]; |
---|
127 | KeyFactory kf = KeyFactory.getInstance("RSA"); |
---|
128 | fl.read ( key, 0, fl.available() ); |
---|
129 | fl.close(); |
---|
130 | PKCS8EncodedKeySpec keysp = new PKCS8EncodedKeySpec ( key ); |
---|
131 | PrivateKey ff = kf.generatePrivate (keysp); |
---|
132 | |
---|
133 | // loading CertificateChain |
---|
134 | CertificateFactory cf = CertificateFactory.getInstance("X.509"); |
---|
135 | InputStream certstream = fullStream (certfile); |
---|
136 | |
---|
137 | Collection c = cf.generateCertificates(certstream) ; |
---|
138 | Certificate[] certs = new Certificate[c.toArray().length]; |
---|
139 | |
---|
140 | if (c.size() == 1) { |
---|
141 | certstream = fullStream (certfile); |
---|
142 | System.out.println("One certificate, no chain."); |
---|
143 | Certificate cert = cf.generateCertificate(certstream) ; |
---|
144 | certs[0] = cert; |
---|
145 | } else { |
---|
146 | System.out.println("Certificate chain length: "+c.size()); |
---|
147 | certs = (Certificate[])c.toArray(new Certificate[0]); |
---|
148 | } |
---|
149 | |
---|
150 | // storing keystore |
---|
151 | ks.setKeyEntry(defaultalias, ff, |
---|
152 | keypass.toCharArray(), |
---|
153 | certs ); |
---|
154 | System.out.println ("Key and certificate stored."); |
---|
155 | System.out.println ("Alias:"+defaultalias+" Password:"+keypass); |
---|
156 | ks.store(new FileOutputStream ( keystorename ), |
---|
157 | keypass.toCharArray()); |
---|
158 | } catch (Exception ex) { |
---|
159 | ex.printStackTrace(); |
---|
160 | } |
---|
161 | } |
---|
162 | |
---|
163 | }// KeyStore |
---|