ImportKeyUtil: ImportKey.java

File ImportKey.java, 6.4 KB (added by jpmitchell@…, 13 years ago)
Line 
1
2import java.security.*;
3import java.io.IOException;
4import java.io.InputStream;
5import java.io.FileInputStream;
6import java.io.DataInputStream;
7import java.io.ByteArrayInputStream;
8import java.io.FileOutputStream;
9import java.security.spec.*;
10import java.security.cert.Certificate;
11import java.security.cert.CertificateFactory;
12import java.util.Collection;
13import 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 **/
49public 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