Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Java Keystore Private Key Extractor
/*
* Copyright 2011 Andrew Kroh
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.io.BufferedInputStream;
import java.io.Console;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.security.KeyStore;
import java.security.cert.Certificate;
import java.security.interfaces.RSAPrivateKey;
import java.util.Arrays;
import java.util.Enumeration;
// import <Base64 encoder class of choice>
/**
* Exports the certificates and private keys from a keystore.
*
* <p>
* To generate a new keystore with self-signed certificate run
* the following command or something similar and complete
* the prompts it asks for:
*
* <pre>
* keytool -genkey -alias selfsigned -keyalg RSA -keysize 2048 \
* -validity 3650 -keystore keystore.jks
*
* Enter keystore password: <enter password here>
* Re-enter new password: <enter password here>
* What is your first and last name?
* [Unknown]:
* What is the name of your organizational unit?
* [Unknown]:
* What is the name of your organization?
* [Unknown]:
* What is the name of your City or Locality?
* [Unknown]:
* What is the name of your State or Province?
* [Unknown]:
* What is the two-letter country code for this unit?
* [Unknown]:
* Is CN=Unknown, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown correct?
* [no]: yes
*
* Enter key password for <selfsigned>
* (RETURN if same as keystore password): <use the same password>
* </pre>
*
* @author Andrew Kroh
*/
public class KeyExtractor
{
public static String toBase64KeyString(String label, byte[] bytes)
{
String base64 = Base64.encodeToString(bytes, true);
StringBuilder sb = new StringBuilder();
sb.append("-----BEGIN " + label + "-----\n");
sb.append(base64 + "\n");
sb.append("-----END " + label + "-----");
return sb.toString();
}
public static String toJavaVariableString(String variable, byte[] encoded)
{
String base64 = Base64.encodeToString(encoded, true);
String[] lines = base64.split("\\n");
StringBuilder sb = new StringBuilder();
sb.append("private static final String " + variable + " = \n");
if (lines.length > 1)
{
int i = 0;
for (i = 0 ; i < lines.length - 1; i++)
{
String line = lines[i];
line = line.replaceAll("\\r", "").replaceAll("\\n", "");
sb.append(" \"" + line + "\" +\n");
}
sb.append(" \"" + lines[i] + "\";");
}
return sb.toString();
}
private static char[] readPassword() throws IOException
{
char[] password = new char[1024];
int charCounter = 0;
int input = 0;
while((input = System.in.read()) != -1)
{
if (input == '\r' || input == '\n')
{
break;
}
else
{
password[charCounter++] = (char)input;
}
}
char[] rtn = new char[charCounter];
System.arraycopy(password, 0, rtn, 0, charCounter);
Arrays.fill(password, ' ');
return rtn;
}
public static void main(String[] args) throws Exception
{
if (args.length != 1)
{
StringBuffer sb = new StringBuffer();
sb.append("Usage: java class [keystore file]\n");
System.out.println(sb.toString());
System.exit(1);
}
// Read the keystore file:
InputStream inputStream = null;
try
{
String filename = args[0];
inputStream = new BufferedInputStream(new FileInputStream(filename));
}
catch (FileNotFoundException e)
{
System.out.println("Unable to open keystore.");
System.exit(1);
}
// Get the keystore password:
Console console = System.console();
char[] password = null;
if (console != null)
{
password = console.readPassword("%s", "Keystore Password: ");
}
else
{
System.out.println("Warning: password will be echoed to display...");
System.out.print("Keystore Password: ");
password = readPassword();
}
// Load the keystore:
KeyStore keyStore = KeyStore.getInstance("JKS");
keyStore.load(inputStream, password);
// Enumerate the certificates and output the certs and private keys:
Enumeration<String> aliases = keyStore.aliases();
while(aliases.hasMoreElements())
{
String alias = aliases.nextElement();
Certificate cert = keyStore.getCertificate(alias);
RSAPrivateKey privateKey = (RSAPrivateKey)keyStore.getKey(alias, password);
System.out.println("-----BEGIN ALIAS " + alias + "-----");
// Certificate contents:
System.out.println(cert);
System.out.println();
// Base 64 encoded certificate:
System.out.println(toBase64KeyString("CERTIFICATE", cert.getEncoded()));
System.out.println();
// Base 64 encoded private key:
if (privateKey != null)
{
byte[] privateKeyByteArray = privateKey.getEncoded();
System.out.println(toBase64KeyString("PRIVATE KEY", privateKeyByteArray));
System.out.println();
byte[] privateKeyExponentByteArray = privateKey.getPrivateExponent().toByteArray();
System.out.println(toBase64KeyString("PRIVATE EXPONENT", privateKeyExponentByteArray));
System.out.println();
}
// Base 64 encoded certificate:
System.out.println(toJavaVariableString("CERT", cert.getEncoded()));
System.out.println();
// Base 64 encoded certificate:
if (privateKey != null)
{
byte[] privateKeyByteArray = privateKey.getEncoded();
System.out.println(toJavaVariableString("PRIVATE KEY", privateKeyByteArray));
System.out.println();
byte[] privateKeyExponentByteArray = privateKey.getPrivateExponent().toByteArray();
System.out.println(toJavaVariableString("PRIVATE_EXPONENT", privateKeyExponentByteArray));
System.out.println();
}
System.out.println("-----END ALIAS " + alias + "-----");
System.out.println();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment