Created
December 24, 2015 09:13
-
-
Save spicydog/84fa0e74d8524fba1fbb to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
openssl x509 -in cert.pem -inform PEM -out cert.der -outform DER | |
openssl x509 -in chain.pem -inform PEM -out chain.der -outform DER | |
openssl pkcs8 -topk8 -nocrypt -in privkey.pem -inform PEM -out privkey.der -outform DER | |
cat cert.der chain.der > chained_certificate.der | |
#javac ImportKey.java | |
java ImportKey privkey.der chained_certificate.der |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.security.*; | |
import java.io.IOException; | |
import java.io.InputStream; | |
import java.io.FileInputStream; | |
import java.io.DataInputStream; | |
import java.io.ByteArrayInputStream; | |
import java.io.FileOutputStream; | |
import java.security.spec.*; | |
import java.security.cert.Certificate; | |
import java.security.cert.CertificateFactory; | |
import java.util.Collection; | |
import java.util.Iterator; | |
/** | |
* ImportKey.java | |
* | |
* <p>This class imports a key and a certificate into a keystore | |
* (<code>$home/keystore.ImportKey</code>). If the keystore is | |
* already present, it is simply deleted. Both the key and the | |
* certificate file must be in <code>DER</code>-format. The key must be | |
* encoded with <code>PKCS#8</code>-format. The certificate must be | |
* encoded in <code>X.509</code>-format.</p> | |
* | |
* <p>Key format:</p> | |
* <p><code>openssl pkcs8 -topk8 -nocrypt -in YOUR.KEY -out YOUR.KEY.der | |
* -outform der</code></p> | |
* <p>Format of the certificate:</p> | |
* <p><code>openssl x509 -in YOUR.CERT -out YOUR.CERT.der -outform | |
* der</code></p> | |
* <p>Import key and certificate:</p> | |
* <p><code>java comu.ImportKey YOUR.KEY.der YOUR.CERT.der</code></p><br /> | |
* | |
* <p><em>Caution:</em> the old <code>keystore.ImportKey</code>-file is | |
* deleted and replaced with a keystore only containing <code>YOUR.KEY</code> | |
* and <code>YOUR.CERT</code>. The keystore and the key has no password; | |
* they can be set by the <code>keytool -keypasswd</code>-command for setting | |
* the key password, and the <code>keytool -storepasswd</code>-command to set | |
* the keystore password. | |
* <p>The key and the certificate is stored under the alias | |
* <code>importkey</code>; to change this, use <code>keytool -keyclone</code>. | |
* | |
* Created: Fri Apr 13 18:15:07 2001 | |
* Updated: Fri Apr 19 11:03:00 2002 | |
* | |
* @author Joachim Karrer, Jens Carlberg | |
* @version 1.1 | |
**/ | |
/** | |
* NOTES AND INSTRUCTIONS | |
* | |
* 1 convert all public keys including intermediate and root CA with .crt or pem to .der with | |
* "openssl x509 -in [in.crt] -inform PEM -out [out.der] -outform DER" | |
* 2. convert private key of .crt or .pem to .der with | |
* "openssl pkcs8 -topk8 -nocrypt -in [in.crt] -inform PEM -out [out.der] -outform DER" | |
* 3. use cat to merge certificate .der files (not a private key) into one file from server to root certificate | |
* 4. compile this file with "javac ImportKey.java", then you will get ImportKey.class | |
* (no need to compile again if you have already compiled once) | |
* 5. run "java ImportKey [privatekey.der] [chained_certificate.der]" | |
* 6. the keystore file will be written as https.keystore | |
* 7. check keystore with command "keytool -list -v -keystore [keystore]" | |
* 8. check "Certificate chain length: ", it should have value more than 1 if you add chain to it | |
* | |
* Edited from source: http://www.agentbob.info/agentbob/79-AB.html | |
* Modification[1]: Comment of Barry Simons on 4/5/07 2:28:36 AM | |
* Modification[2]: Comment of johann renck on 9/3/07 3:31:49 PM | |
* Modification[3]: Add note by spicydog on 2015-10-05T17:53:29Z+0700 | |
* Modification[4]: Modify script for Let's Encrypt by spicydog on 2015-12-24 16:02:01Z+0700 | |
* | |
**/ | |
public class ImportKey { | |
/** | |
* <p>Creates an InputStream from a file, and fills it with the complete | |
* file. Thus, available() on the returned InputStream will return the | |
* full number of bytes the file contains</p> | |
* @param fname The filename | |
* @return The filled InputStream | |
* @exception IOException, if the Streams couldn't be created. | |
**/ | |
private static InputStream fullStream ( String fname ) throws IOException { | |
FileInputStream fis = new FileInputStream(fname); | |
DataInputStream dis = new DataInputStream(fis); | |
byte[] bytes = new byte[dis.available()]; | |
dis.readFully(bytes); | |
ByteArrayInputStream bais = new ByteArrayInputStream(bytes); | |
return bais; | |
} | |
/** | |
* <p>Takes two file names for a key and the certificate for the key, | |
* and imports those into a keystore. Optionally it takes an alias | |
* for the key. | |
* <p>The first argument is the filename for the key. The key should be | |
* in PKCS8-format. | |
* <p>The second argument is the filename for the certificate for the key. | |
* <p>If a third argument is given it is used as the alias. If missing, | |
* the key is imported with the alias importkey | |
* <p>The name of the keystore file can be controlled by setting | |
* the keystore property (java -Dkeystore=mykeystore). If no name | |
* is given, the file is named <code>keystore.ImportKey</code> | |
* and placed in your home directory. | |
* @param args [0] Name of the key file, [1] Name of the certificate file | |
* [2] Alias for the key. | |
**/ | |
public static void main ( String args[]) { | |
// change this if you want another password by default | |
String keypass = "password"; | |
// change this if you want another alias by default | |
String defaultalias = "alias"; | |
// change this if you want another keystorefile by default | |
String keystorename = System.getProperty("keystore"); | |
if (keystorename == null) | |
keystorename = "keystore.ImportKey"; | |
// parsing command line input | |
String keyfile = ""; | |
String certfile = ""; | |
if (args.length < 2 || args.length>3) { | |
System.out.println("Usage: java comu.ImportKey keyfile certfile [alias]"); | |
System.exit(0); | |
} else { | |
keyfile = args[0]; | |
certfile = args[1]; | |
if (args.length>2) | |
defaultalias = args[2]; | |
} | |
try { | |
// initializing and clearing keystore | |
KeyStore ks = KeyStore.getInstance("JKS", "SUN"); | |
ks.load( null , keypass.toCharArray()); | |
System.out.println("Using keystore-file : "+keystorename); | |
ks.store(new FileOutputStream ( keystorename ), | |
keypass.toCharArray()); | |
ks.load(new FileInputStream ( keystorename ), | |
keypass.toCharArray()); | |
// loading Key | |
InputStream fl = fullStream (keyfile); | |
byte[] key = new byte[fl.available()]; | |
KeyFactory kf = KeyFactory.getInstance("RSA"); | |
fl.read ( key, 0, fl.available() ); | |
fl.close(); | |
PKCS8EncodedKeySpec keysp = new PKCS8EncodedKeySpec ( key ); | |
PrivateKey ff = kf.generatePrivate (keysp); | |
// loading CertificateChain | |
CertificateFactory cf = CertificateFactory.getInstance("X.509"); | |
InputStream certstream = fullStream (certfile); | |
Collection c = cf.generateCertificates(certstream) ; | |
Certificate[] certs = new Certificate[c.toArray().length]; | |
if (c.size() == 1) { | |
certstream = fullStream (certfile); | |
System.out.println("One certificate, no chain."); | |
Certificate cert = cf.generateCertificate(certstream) ; | |
certs[0] = cert; | |
} else { | |
System.out.println("Certificate chain length: "+c.size()); | |
/** | |
* Run for through chained certificates | |
**/ | |
// certs = (Certificate[])c.toArray(); | |
int i = 0; | |
Iterator it = c.iterator(); | |
while (it.hasNext()) { | |
certs[i] = (Certificate)it.next(); | |
i++; | |
} | |
} | |
// storing keystore | |
ks.setKeyEntry(defaultalias, ff, | |
keypass.toCharArray(), | |
certs ); | |
System.out.println ("Key and certificate stored."); | |
System.out.println ("Alias:"+defaultalias+" Password:"+keypass); | |
ks.store(new FileOutputStream ( keystorename ), | |
keypass.toCharArray()); | |
} catch (Exception ex) { | |
ex.printStackTrace(); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment