KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sourceforge > jcetaglib > tools > KeyTools


1 package net.sourceforge.jcetaglib.tools;
2
3 import net.sourceforge.jcetaglib.lib.CertTools;
4 import org.bouncycastle.asn1.DERBMPString;
5 import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
6 import org.bouncycastle.jce.interfaces.PKCS12BagAttributeCarrier;
7
8 import javax.crypto.Cipher;
9 import javax.crypto.EncryptedPrivateKeyInfo;
10 import javax.crypto.SecretKeyFactory;
11 import javax.crypto.spec.PBEKeySpec;
12 import javax.crypto.spec.PBEParameterSpec;
13 import java.io.ByteArrayInputStream JavaDoc;
14 import java.security.*;
15 import java.security.cert.Certificate JavaDoc;
16 import java.security.cert.CertificateFactory JavaDoc;
17 import java.security.cert.X509Certificate JavaDoc;
18 import java.security.spec.PKCS8EncodedKeySpec JavaDoc;
19 import java.util.ArrayList JavaDoc;
20
21 /**
22  * Tools to handle common key and keystore operations.
23  *
24  * @version $Id: KeyTools.java,v 1.4 2004/04/15 07:28:36 hamgert Exp $
25  */

26 public class KeyTools {
27
28     //private static Category cat = Category.getInstance(KeyTools.class.getName());
29

30
31     private static byte[] salt = {
32         (byte) 0x23, (byte) 0xc8, (byte) 0x99, (byte) 0x8c,
33         (byte) 0xc4, (byte) 0xff, (byte) 0xee, (byte) 0x7d
34     }; // Salt
35

36     private static int count = 100; // Iteration count
37
private static String JavaDoc alg = "1.2.840.113549.1.12.1.3"; // 3 key triple DES with SHA-1
38

39
40     /** Prevent from creating new KeyTools object*/
41     private KeyTools() {
42     }
43
44     /**
45      * Creates PKCS12-file that can be imported in IE or Netscape.
46      * The alias for the private key is set to 'privateKey' and the private key password is null.
47      * @param alias the alias used for the key entry
48      * @param privKey RSA private key
49      * @param cert user certificate
50      * @param cacert CA-certificate or null if only one cert in chain, in that case use 'cert'.
51      * @return byte[] containing PKCS12-file in binary format
52      * @exception Exception if input parameters are not OK or certificate generation fails
53      */

54     static public KeyStore createP12(String JavaDoc alias, PrivateKey privKey, X509Certificate JavaDoc cert, X509Certificate JavaDoc cacert)
55             throws Exception JavaDoc {
56         Certificate JavaDoc[] chain;
57         if (cacert == null)
58             chain = null;
59         else {
60             chain = new Certificate JavaDoc[1];
61             chain[0] = cacert;
62         }
63         return createP12(alias, privKey, cert, chain);
64     } // createP12
65

66     /**
67      * Creates PKCS12-file that can be imported in IE or Netscape.
68      * The alias for the private key is set to 'privateKey' and the private key password is null.
69      * @param alias the alias used for the key entry
70      * @param privKey RSA private key
71      * @param cert user certificate
72      * @param cachain CA-certificate chain or null if only one cert in chain, in that case use 'cert'.
73      * @return byte[] containing PKCS12-file in binary format
74      * @exception Exception if input parameters are not OK or certificate generation fails
75      */

76     static public KeyStore createP12(String JavaDoc alias, PrivateKey privKey, X509Certificate JavaDoc cert, Certificate JavaDoc[] cachain)
77             throws Exception JavaDoc {
78         // Certificate chain, only max two levels deep unforturnately, this is a TODO:
79
if (cert == null)
80             throw new IllegalArgumentException JavaDoc("Parameter cert cannot be null.");
81         int len = 1;
82         if (cachain != null)
83             len += cachain.length;
84         Certificate JavaDoc[] chain = new Certificate JavaDoc[len];
85         // To not get a ClassCastException we need to genereate a real new certificate with BC
86
CertificateFactory JavaDoc cf = CertificateFactory.getInstance("X.509", "BC");
87         chain[0] = cf.generateCertificate(new ByteArrayInputStream JavaDoc(cert.getEncoded()));
88         if (cachain != null)
89             for (int i = 0; i < cachain.length; i++) {
90                 X509Certificate JavaDoc tmpcert = (X509Certificate JavaDoc) cf.generateCertificate(new ByteArrayInputStream JavaDoc(cachain[i].getEncoded()));
91                 chain[i + 1] = tmpcert;
92             }
93
94
95         if (chain.length > 1) {
96             for (int i = 1; i < chain.length; i++) {
97                 X509Certificate JavaDoc cacert = (X509Certificate JavaDoc) cf.generateCertificate(new ByteArrayInputStream JavaDoc(chain[i].getEncoded()));
98                 // Set attributes on CA-cert
99
PKCS12BagAttributeCarrier caBagAttr = (PKCS12BagAttributeCarrier) chain[i];
100                 String JavaDoc cafriendly = CertTools.getPartFromDN(cacert.getSubjectDN().toString(), "CN");
101                 caBagAttr.setBagAttribute(PKCSObjectIdentifiers.pkcs_9_at_friendlyName, new DERBMPString(cafriendly));
102             }
103         }
104         // Set attributes on user-cert
105
PKCS12BagAttributeCarrier certBagAttr = (PKCS12BagAttributeCarrier) chain[0];
106         certBagAttr.setBagAttribute(PKCSObjectIdentifiers.pkcs_9_at_friendlyName, new DERBMPString(alias));
107         // in this case we just set the local key id to that of the public key
108
certBagAttr.setBagAttribute(PKCSObjectIdentifiers.pkcs_9_at_localKeyId, CertTools.createSubjectKeyId(chain[0].getPublicKey()));
109
110         // "Clean" private key, i.e. remove any old attributes
111
KeyFactory keyfact = KeyFactory.getInstance(privKey.getAlgorithm(), "BC");
112         PrivateKey pk = keyfact.generatePrivate(new PKCS8EncodedKeySpec JavaDoc(privKey.getEncoded()));
113         // Set attributes for private key
114
PKCS12BagAttributeCarrier keyBagAttr = (PKCS12BagAttributeCarrier) pk;
115         // in this case we just set the local key id to that of the public key
116
keyBagAttr.setBagAttribute(PKCSObjectIdentifiers.pkcs_9_at_friendlyName, new DERBMPString(alias));
117         keyBagAttr.setBagAttribute(PKCSObjectIdentifiers.pkcs_9_at_localKeyId, CertTools.createSubjectKeyId(chain[0].getPublicKey()));
118
119         // store the key and the certificate chain
120
KeyStore store = KeyStore.getInstance("PKCS12", "BC");
121         store.load(null, null);
122         store.setKeyEntry(alias, pk, null, chain);
123         return store;
124     } // createP12
125

126     /** Retrieves the certificate chain from a keystore.
127      * @param keyStore the keystore, which has been loaded and opened.
128      * @param privateKeyAlias the alias of the privatekey for which the certchain belongs.
129      * @return array of Certificate, length of array is 0 if no certificates are found.
130      */

131     public static Certificate JavaDoc[] getCertChain(KeyStore keyStore, String JavaDoc privateKeyAlias) throws KeyStoreException {
132
133         Certificate JavaDoc[] certchain = keyStore.getCertificateChain(privateKeyAlias);
134
135         if (certchain.length < 1) {
136             System.out.println("Cannot load certificate chain with alias '" + privateKeyAlias + "' from keystore.");
137             return certchain;
138         } else if (certchain.length > 0) {
139             if (CertTools.isSelfSigned((X509Certificate JavaDoc) certchain[certchain.length - 1])) {
140                 return certchain;
141             }
142         }
143
144         // If we came here, we have a cert which is not root cert in 'cert'
145
ArrayList JavaDoc array = new ArrayList JavaDoc();
146         for (int i = 0; i < certchain.length; i++) {
147             array.add(certchain[i]);
148         }
149
150         boolean stop = false;
151         while (!stop) {
152             X509Certificate JavaDoc cert = (X509Certificate JavaDoc) array.get(array.size() - 1);
153             String JavaDoc ialias = CertTools.getPartFromDN(cert.getIssuerDN().toString(), "CN");
154             Certificate JavaDoc[] chain1 = keyStore.getCertificateChain(ialias);
155             if (chain1 == null) {
156                 stop = true;
157             } else {
158                 if (chain1.length == 0) {
159                     System.out.println("No RootCA certificate found!");
160                     stop = true;
161                 }
162                 for (int j = 0; j < chain1.length; j++) {
163                     array.add(chain1[j]);
164                     // If one cert is slefsigned, we have found a root certificate, we don't need to go on anymore
165
if (CertTools.isSelfSigned((X509Certificate JavaDoc) chain1[j]))
166                         stop = true;
167                 }
168             }
169         }
170         Certificate JavaDoc[] ret = new Certificate JavaDoc[array.size()];
171         for (int i = 0; i < ret.length; i++) {
172             ret[i] = (X509Certificate JavaDoc) array.get(i);
173         }
174         return ret;
175     } // getCertChain
176

177     /** decrypts an RSA private key.
178      * @param wrappedKey the key in bytes
179      * @param password password as string
180      * @return PrivateKey structure
181      */

182     public static PrivateKey decryptPrivateKey(byte[] wrappedKey, String JavaDoc password)
183             throws Exception JavaDoc {
184         PBEParameterSpec defParams = new PBEParameterSpec(salt, count);
185
186         AlgorithmParameters params = AlgorithmParameters.getInstance(alg, "BC");
187
188         params.init(defParams);
189
190         //
191
// set up the key
192
//
193

194         EncryptedPrivateKeyInfo privKeyInfo = new EncryptedPrivateKeyInfo(params, wrappedKey);
195
196
197         PBEKeySpec pbeSpec = new PBEKeySpec(password.toCharArray());
198         SecretKeyFactory keyFact = SecretKeyFactory.getInstance(alg, "BC");
199         Cipher cipher = Cipher.getInstance(alg, "BC");
200
201         cipher.init(Cipher.DECRYPT_MODE, keyFact.generateSecret(pbeSpec), privKeyInfo.getAlgParameters());
202
203
204         PKCS8EncodedKeySpec JavaDoc keySpec = privKeyInfo.getKeySpec(cipher);
205
206         KeyFactory kf = KeyFactory.getInstance("RSA");
207         PrivateKey privKey = kf.generatePrivate(keySpec);
208
209         return privKey;
210     } //decryptPrivateKey
211

212 } // KeyTools//
213
Popular Tags